| <?xml version='1.0' encoding='utf-8'?> |
| |
| <refentry id='gvariant-format-strings'> |
| <refmeta> |
| <refentrytitle>GVariant Format Strings</refentrytitle> |
| </refmeta> |
| <refnamediv> |
| <refname>GVariant Format Strings</refname> |
| <refpurpose>varargs conversion of GVariants</refpurpose> |
| </refnamediv> |
| |
| <refsect1> |
| <title>Variable Argument Conversions</title> |
| |
| <para> |
| This page attempts to document how to perform variable argument |
| conversions with GVariant. |
| </para> |
| <para> |
| Conversions occur according to format strings. A format string is a two-way mapping between a single |
| <link linkend='GVariant'>GVariant</link> value and one or more C values. |
| </para> |
| <para> |
| A conversion from C values into a <link linkend='GVariant'>GVariant</link> value is made using the |
| <link linkend='g-variant-new'><function>g_variant_new()</function></link> function. A conversion from a |
| <link linkend='GVariant'>GVariant</link> into C values is made using the |
| <link linkend='g-variant-get'><function>g_variant_get()</function></link> function. |
| </para> |
| </refsect1> |
| |
| <refsect1> |
| <title>Syntax</title> |
| |
| <para> |
| This section exhaustively describes all possibilities for GVariant format strings. There are no valid forms of |
| format strings other than those described here. Please note that the format string syntax is likely to expand in the |
| future. |
| </para> |
| <para> |
| Valid format strings have one of the following forms: |
| </para> |
| <itemizedlist> |
| <listitem> |
| <para>any type string</para> |
| </listitem> |
| <listitem> |
| <para> |
| a type string prefixed with a '<literal>@</literal>' |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| '<literal>&s</literal>' '<literal>&o</literal>', '<literal>&g</literal>', '<literal>^as</literal>', |
| '<literal>^a&s</literal>', '<literal>^ao</literal>', '<literal>^a&o</literal>','<literal>^ay</literal>', |
| '<literal>^&ay</literal>', '<literal>^aay</literal>' or '<literal>^a&ay</literal>'. |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| any format string, prefixed with an '<literal>m</literal>' |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| a sequence of zero or more format strings, concatenated and enclosed in parentheses |
| </para> |
| </listitem> |
| <listitem> |
| <para> |
| an opening brace, followed by two format strings, followed by a closing brace (subject to the constraint that the |
| first format string correspond to a type valid for use as the key type of a dictionary) |
| </para> |
| </listitem> |
| </itemizedlist> |
| </refsect1> |
| <refsect1> |
| <title>Symbols</title> |
| |
| <para> |
| The following table describes the rough meaning of symbols that may appear inside a GVariant format string. Each |
| symbol is described in detail in its own section, including usage examples. |
| </para> |
| |
| <informaltable> |
| <tgroup cols='2'> |
| <colspec colname='col_0'/> |
| <colspec colname='col_1'/> |
| <tbody> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'>Symbol</emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'>Meaning</emphasis> |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>b</literal>, <literal>y</literal>, <literal>n</literal>, <literal>q</literal>, <literal>i</literal>, |
| <literal>u</literal>, <literal>x</literal>, <literal>t</literal>, <literal>h</literal>, <literal>d</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| Used for building or deconstructing boolean, byte and numeric types. See |
| <link linkend='gvariant-format-strings-numeric-types'>Numeric Types</link> below. |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>s</literal>, <literal>o</literal>, <literal>g</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| Used for building or deconstructing string types. See |
| <link linkend='gvariant-format-strings-strings'>Strings</link> below. |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'><literal>v</literal></emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| Used for building or deconstructing variant types. See |
| <link linkend='gvariant-format-strings-variants'>Variants</link> below. |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>a</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| Used for building or deconstructing arrays. See |
| <link linkend='gvariant-format-strings-arrays'>Arrays</link> below. |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>m</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| Used for building or deconstructing maybe types. See |
| <link linkend='gvariant-format-strings-maybe-types'>Maybe Types</link> below. |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>()</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| Used for building or deconstructing tuples. See |
| <link linkend='gvariant-format-strings-tuples'>Tuples</link> below. |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>{}</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| Used for building or deconstructing dictionary entries. See |
| <link linkend='gvariant-format-strings-dictionaries'>Dictionaries</link> below. |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>@</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| Used as a prefix for a GVariant type string (not a prefix for a format string, so <literal>@as</literal> is |
| a valid format string but <literal>@^as</literal> is not). Denotes that a pointer to a |
| <link linkend='GVariant'>GVariant</link> should be used in place of the normal C type or types. For |
| <link linkend='g-variant-new'><function>g_variant_new()</function></link> this means that you must pass a |
| non-<link linkend='NULL:CAPS'><literal>NULL</literal></link> <code>(<link linkend='GVariant'>GVariant</link> |
| *)</code>; if it is a floating reference, ownership will be taken, as |
| if by using <link linkend="g-variant-ref-sink"><function>g_variant_ref_sink()</function></link>. |
| For <link linkend='g-variant-get'><function>g_variant_get()</function></link> this means that you |
| must pass a pointer to a <code>(<link linkend='GVariant'>GVariant</link> *)</code> for the value to be returned |
| by reference or <link linkend='NULL:CAPS'><literal>NULL</literal></link> to ignore the value. See |
| <link linkend='gvariant-format-strings-gvariant'><code>GVariant *</code></link> below. |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>*</literal>, <literal>?</literal>, <literal>r</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| Exactly equivalent to <literal>@*</literal>, <literal>@?</literal> and <literal>@r</literal>. Provided only for |
| completeness so that all GVariant type strings can be used also as format strings. See <link |
| linkend='gvariant-format-strings-gvariant'><code>GVariant *</code></link> below. |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'><literal>&</literal></emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| Used as a prefix for a GVariant type string (not a prefix for a format string, so <literal>&s</literal> is |
| a valid format string but <literal>&@s</literal> is not). |
| Denotes that a C pointer to serialised data |
| should be used in place of the normal C type. See |
| <link linkend='gvariant-format-strings-pointers'>Pointers</link> below. |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'><literal>^</literal></emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| Used as a prefix on some specific types of format strings. See |
| <link linkend='gvariant-format-strings-convenience'>Convenience Conversions</link> below. |
| </para> |
| </entry> |
| </row> |
| </tbody> |
| </tgroup> |
| </informaltable> |
| |
| |
| <refsect2 id='gvariant-format-strings-numeric-types'> |
| <title>Numeric Types</title> |
| <para> |
| <emphasis role='strong'> |
| Characters: <literal>b</literal>, <literal>y</literal>, <literal>n</literal>, <literal>q</literal>, |
| <literal>i</literal>, <literal>u</literal>, <literal>x</literal>, <literal>t</literal>, <literal>h</literal>, |
| <literal>d</literal> |
| </emphasis> |
| </para> |
| |
| <para> |
| Variable argument conversions from numeric types work in the most obvious way possible. Upon encountering one of |
| these characters, <link linkend='g-variant-new'><function>g_variant_new()</function></link> takes the equivalent C |
| type as an argument. <link linkend='g-variant-get'><function>g_variant_get()</function></link> takes a pointer to |
| the equivalent C type (or <link linkend='NULL:CAPS'><literal>NULL</literal></link> to ignore the value). |
| </para> |
| |
| <para> |
| The equivalent C types are as follows: |
| </para> |
| |
| <informaltable> |
| <tgroup cols='2'> |
| <colspec colname='col_0'/><colspec colname='col_1'/> |
| <tbody> |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'>Character</emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'>Equivalent C type</emphasis> |
| </para> |
| </entry> |
| </row> |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>b</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <link linkend='gboolean'><type>gboolean</type></link> |
| </para> |
| </entry> |
| </row> |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>y</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <link linkend='guchar'><type>guchar</type></link> |
| </para> |
| </entry> |
| </row> |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>n</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <link linkend='gint16'><type>gint16</type></link> |
| </para> |
| </entry> |
| </row> |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>q</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <link linkend='guint16'><type>guint16</type></link> |
| </para> |
| </entry> |
| </row> |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>i</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <link linkend='gint32'><type>gint32</type></link> |
| </para> |
| </entry> |
| </row> |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>u</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <link linkend='guint32'><type>guint32</type></link> |
| </para> |
| </entry> |
| </row> |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>x</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <link linkend='gint64'><type>gint64</type></link> |
| </para> |
| </entry> |
| </row> |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>t</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <link linkend='guint64'><type>guint64</type></link> |
| </para> |
| </entry> |
| </row> |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>h</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <link linkend='gint32'><type>gint32</type></link> |
| </para> |
| </entry> |
| </row> |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>d</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <link linkend='gdouble'><type>gdouble</type></link> |
| </para> |
| </entry> |
| </row> |
| </tbody> |
| </tgroup> |
| </informaltable> |
| |
| <anchor id='gvariant-varargs'/> |
| <para> |
| Note that in C, small integer types in variable argument lists are promoted up to <link |
| linkend='gint'><type>int</type></link> or <link linkend='guint'><type>unsigned int</type></link> as appropriate, and |
| read back accordingly. <link linkend='gint'><type>int</type></link> is 32 bits on every platform on which GLib is |
| currently supported. This means that you can use C expressions of type <link linkend='gint'><type>int</type></link> |
| with <link linkend='g-variant-new'><function>g_variant_new()</function></link> and format characters |
| '<literal>b</literal>', '<literal>y</literal>', '<literal>n</literal>', '<literal>q</literal>', |
| '<literal>i</literal>', '<literal>u</literal>' and '<literal>h</literal>'. Specifically, you can use integer |
| literals with these characters. |
| </para> |
| |
| <para> |
| When using the '<literal>x</literal>' and '<literal>t</literal>' characters, you must ensure that the value that you |
| provide is 64 bit. This means that you should use a cast or make use of the |
| <link linkend='G-GINT64-CONSTANT:CAPS'><literal>G_GINT64_CONSTANT</literal></link> or |
| <link linkend='G-GUINT64-CONSTANT:CAPS'><literal>G_GUINT64_CONSTANT</literal></link> macros. |
| </para> |
| |
| <para> |
| No type promotion occurs when using <link linkend='g-variant-get'><function>g_variant_get()</function></link> since |
| it operates with pointers. The pointers must always point to a memory region of exactly the correct size. |
| </para> |
| |
| <refsect3> |
| <title>Examples</title> |
| <informalexample><programlisting> |
| <![CDATA[GVariant *value1, *value2, *value3, *value4; |
| |
| value1 = g_variant_new ("y", 200); |
| value2 = g_variant_new ("b", TRUE); |
| value3 = g_variant_new ("d", 37.5): |
| value4 = g_variant_new ("x", G_GINT64_CONSTANT (998877665544332211)); |
| |
| { |
| gdouble floating; |
| gboolean truth; |
| gint64 bignum; |
| |
| |
| g_variant_get (value1, "y", NULL); /* ignore the value. */ |
| g_variant_get (value2, "b", &truth); |
| g_variant_get (value3, "d", &floating); |
| g_variant_get (value4, "x", &bignum); |
| }]]></programlisting></informalexample> |
| </refsect3> |
| </refsect2> |
| |
| <refsect2 id='gvariant-format-strings-strings'> |
| <title>Strings</title> |
| <para> |
| <emphasis role='strong'> |
| Characters: <literal>s</literal>, <literal>o</literal>, <literal>g</literal> |
| </emphasis> |
| </para> |
| |
| <para> |
| String conversions occur to and from standard nul-terminated C strings. Upon encountering an |
| '<literal>s</literal>', '<literal>o</literal>' or '<literal>g</literal>' in a format string, |
| <link linkend='g-variant-new'><function>g_variant_new()</function></link> takes a <code>(const |
| <link linkend='gchar'>gchar</link> *)</code> and makes a copy of it. |
| <link linkend='NULL:CAPS'><literal>NULL</literal></link> is not a valid string; use |
| <link linkend='gvariant-format-strings-maybe-types'>maybe types</link> to encode that. If the '<literal>o</literal>' or |
| '<literal>g</literal>' characters are used, care must be taken to ensure that the passed string is a valid DBus |
| object path or DBus type signature, respectively. |
| </para> |
| <para> |
| Upon encounting '<literal>s</literal>', '<literal>o</literal>' or '<literal>g</literal>', <link |
| linkend='g-variant-get'><function>g_variant_get()</function></link> takes a pointer to a |
| <code>(<link linkend='gchar'>gchar</link> *)</code> (ie: <code>(<link linkend='gchar'>gchar</link> **)</code>) and |
| sets it to a newly-allocated copy of the string. It is appropriate to free this copy using |
| <link linkend='g-free'><function>g_free()</function></link>. |
| <link linkend='NULL:CAPS'><literal>NULL</literal></link> may also be passed to indicate that the value of the |
| string should be ignored (in which case no copy is made). |
| </para> |
| |
| <refsect3> |
| <title>Examples</title> |
| <informalexample><programlisting> |
| <![CDATA[GVariant *value1, *value2, *value3; |
| |
| value1 = g_variant_new ("s", "hello world!"); |
| value2 = g_variant_new ("o", "/must/be/a/valid/path"); |
| value3 = g_variant_new ("g", "iias"); |
| |
| #if 0 |
| g_variant_new ("s", NULL); /* not valid: NULL is not a string. */ |
| #endif |
| |
| { |
| gchar *result; |
| |
| g_variant_get (value1, "s", &result); |
| g_print ("It was '%s'\n", result); |
| g_free (result); |
| }]]></programlisting></informalexample> |
| </refsect3> |
| </refsect2> |
| |
| <refsect2 id='gvariant-format-strings-variants'> |
| <title>Variants</title> |
| <para> |
| <emphasis role='strong'> |
| Characters: <literal>v</literal> |
| </emphasis> |
| </para> |
| |
| <para> |
| Upon encountering a '<literal>v</literal>', |
| <link linkend='g-variant-new'><function>g_variant_new()</function></link> takes a <code>(<link |
| linkend='GVariant'>GVariant</link> *)</code>. The value of the |
| <link linkend='GVariant'><type>GVariant</type></link> is used as the contents of the variant value. |
| </para> |
| <para> |
| Upon encountering a '<literal>v</literal>', <link |
| linkend='g-variant-get'><function>g_variant_get()</function></link> takes a pointer to a |
| <code>(<link linkend='GVariant'>GVariant</link> *)</code> (ie: <code>(<link linkend='GVariant'>GVariant</link> **) |
| </code>). It is set to a new reference to a <link linkend='GVariant'><type>GVariant</type></link> instance |
| containing the contents of the variant value. It is appropriate to free this reference using |
| <link linkend='g-variant-unref'><function>g_variant_unref()</function></link>. |
| <link linkend='NULL:CAPS'><literal>NULL</literal></link> may also be passed to indicate that the value should be |
| ignored (in which case no new reference is created). |
| </para> |
| |
| <refsect3> |
| <title>Examples</title> |
| <informalexample><programlisting> |
| <![CDATA[GVariant *x, *y; |
| |
| /* the following two lines are equivalent: */ |
| x = g_variant_new ("v", y); |
| x = g_variant_new_variant (y); |
| |
| /* as are these: */ |
| g_variant_get (x, "v", &y); |
| y = g_variant_get_variant (x);]]></programlisting></informalexample> |
| </refsect3> |
| </refsect2> |
| |
| |
| <refsect2 id='gvariant-format-strings-arrays'> |
| <title>Arrays</title> |
| <para> |
| <emphasis role='strong'> |
| Characters: <literal>a</literal> |
| </emphasis> |
| </para> |
| |
| <para> |
| Upon encountering an '<literal>a</literal>' character followed by a type string, |
| <link linkend='g-variant-new'><function>g_variant_new()</function></link> will take a |
| <code>(<link linkend='GVariantBuilder'>GVariantBuilder</link> *)</code> that has been created as an array builder |
| for an array of the type given in the type string. The builder will have |
| <link linkend='g-variant-builder-end'><function>g_variant_builder_end()</function></link> called on it and the |
| result will be used as the value. As a special exception, if the given type string is a definite type, then |
| <link linkend='NULL:CAPS'><literal>NULL</literal></link> may be given to mean an empty array of that type. |
| </para> |
| |
| <para> |
| Upon encountering an '<literal>a</literal>' character followed by a type string, |
| <link linkend='g-variant-get'><function>g_variant_get()</function></link> will take a pointer to a |
| <code>(<link linkend='GVariantIter'>GVariantIter</link> *)</code> (ie: |
| <code>(<link linkend='GVariantIter'>GVariantIter</link> **)</code>). |
| A new heap-allocated iterator is created and returned, initialised for iterating over the elements of the array. |
| This iterator should be freed when you are done with it, using |
| <link linkend='g-variant-iter-free'><function>g_variant_iter_free()</function></link>. |
| <link linkend='NULL:CAPS'><literal>NULL</literal></link> may also be given to indicate that the value of the array |
| should be ignored. |
| </para> |
| |
| <refsect3> |
| <title>Examples</title> |
| <informalexample><programlisting> |
| <![CDATA[GVariantBuilder *builder; |
| GVariant *value; |
| |
| builder = g_variant_builder_new (G_VARIANT_TYPE ("as")); |
| g_variant_builder_add (builder, "s", "when"); |
| g_variant_builder_add (builder, "s", "in"); |
| g_variant_builder_add (builder, "s", "the"); |
| g_variant_builder_add (builder, "s", "course"); |
| value = g_variant_new ("as", builder); |
| g_variant_builder_unref (builder); |
| |
| { |
| GVariantIter *iter; |
| gchar *str; |
| |
| g_variant_get (value, "as", &iter); |
| while (g_variant_iter_loop (iter, "s", &str)) |
| g_print ("%s\n", str); |
| g_variant_iter_free (iter); |
| } |
| |
| g_variant_unref (value);]]></programlisting></informalexample> |
| </refsect3> |
| </refsect2> |
| |
| <refsect2 id='gvariant-format-strings-maybe-types'> |
| <title>Maybe Types</title> |
| <para> |
| <emphasis role='strong'> |
| Characters: <literal>m</literal> |
| </emphasis> |
| </para> |
| <para> |
| Maybe types are handled in two separate ways depending on the format string that follows the |
| '<literal>m</literal>'. The method that is used currently depends entirely on the character immediately following the |
| '<literal>m</literal>'. |
| </para> |
| |
| <para> |
| The first way is used with format strings starting with '<literal>a</literal>', '<literal>s</literal>', |
| '<literal>o</literal>', '<literal>g</literal>', '<literal>v</literal>', '<literal>@</literal>', |
| '<literal>*</literal>', '<literal>?</literal>', '<literal>r</literal>', '<literal>&</literal>', or |
| '<literal>^</literal>'. In all of these cases, for non-maybe types, |
| <link linkend='g-variant-new'><function>g_variant_new()</function></link> takes a pointer to a |
| non-<link linkend='NULL:CAPS'><literal>NULL</literal></link> value and |
| <link linkend='g-variant-get'><function>g_variant_get()</function></link> returns (by reference) a |
| non-<link linkend='NULL:CAPS'><literal>NULL</literal></link> pointer. When any of these format strings are |
| prefixed with an '<literal>m</literal>', the type of arguments that are collected does not change in any way, but |
| <link linkend='NULL:CAPS'><literal>NULL</literal></link> becomes a permissable value, to indicate the Nothing case. |
| </para> |
| <para> |
| Note that the "special exception" introduced in the array section for constructing empty arrays is ignored |
| here. Using a <literal>NULL</literal> pointer with the format string '<literal>mas</literal>' constructs |
| the Nothing value -- not an empty array. |
| </para> |
| <para> |
| The second way is used with all other format strings. For |
| <link linkend='g-variant-new'><function>g_variant_new()</function></link> an additional |
| <link linkend='gboolean'><type>gboolean</type></link> argument is collected and for |
| <link linkend='g-variant-get'><function>g_variant_get()</function></link> an additional |
| <code>(<link linkend='gboolean'>gboolean</link> *)</code>. Following this argument, the arguments that are normally |
| collected for the equivalent non-maybe type will be collected. |
| </para> |
| <para> |
| If <link linkend='FALSE:CAPS'><literal>FALSE</literal></link> is given to |
| <link linkend='g-variant-new'><function>g_variant_new()</function></link> then the Nothing value is constructed and |
| the collected arguments are ignored. Otherwise (if <link linkend='TRUE:CAPS'><literal>TRUE</literal></link> was |
| given), the arguments are used in the normal way to create the Just value. |
| </para> |
| <para> |
| If <link linkend='NULL:CAPS'><literal>NULL</literal></link> is given to |
| <link linkend='g-variant-get'><function>g_variant_get()</function></link> then the value is ignored. If a |
| non-<link linkend='NULL:CAPS'><literal>NULL</literal></link> pointer is given then it is used to return by reference |
| whether the value was Just. In the case that the value was Just, the |
| <link linkend='gboolean'><type>gboolean</type></link> will be set to |
| <link linkend='TRUE:CAPS'><literal>TRUE</literal></link> and the value will be stored in the arguments in the usual |
| way. In the case that the value was Nothing, the <link linkend='gboolean'><type>gboolean</type></link> will be set to |
| <link linkend='FALSE:CAPS'><literal>FALSE</literal></link> and the arguments will be collected in the normal way |
| but have their values set to binary zero. |
| </para> |
| |
| <refsect3> |
| <title>Examples</title> |
| <informalexample><programlisting> |
| <![CDATA[GVariant *value1, *value2, *value3, *value4, *value5, *value6; |
| value1 = g_variant_new ("ms", "Hello world"); |
| value2 = g_variant_new ("ms", NULL); |
| value3 = g_variant_new ("(m(ii)s)", TRUE, 123, 456, "Done"); |
| value4 = g_variant_new ("(m(ii)s)", FALSE, -1, -1, "Done"); /* both '-1' are ignored. */ |
| value5 = g_variant_new ("(m@(ii)s)", NULL, "Done"); |
| |
| { |
| GVariant *contents; |
| const gchar *cstr; |
| gboolean just; |
| gint32 x, y; |
| gchar *str; |
| |
| g_variant_get (value1, "ms", &str); |
| if (str != NULL) |
| g_print ("str: %s\n", str); |
| else |
| g_print ("it was null\n"); |
| g_free (str); |
| |
| |
| g_variant_get (value2, "m&s", &cstr); |
| if (cstr != NULL) |
| g_print ("str: %s\n", cstr); |
| else |
| g_print ("it was null\n"); |
| /* don't free 'cstr' */ |
| |
| |
| /* NULL passed for the gboolean *, but two 'gint32 *' still collected */ |
| g_variant_get (value3, "(m(ii)s)", NULL, NULL, NULL, &str); |
| g_print ("string is %s\n", str); |
| g_free (str); |
| |
| /* note: &s used, so g_free() not needed */ |
| g_variant_get (value4, "(m(ii)&s)", &just, &x, &y, &cstr); |
| if (just) |
| g_print ("it was (%d, %d)\n", x, y); |
| else |
| g_print ("it was null\n"); |
| g_print ("string is %s\n", cstr); |
| /* don't free 'cstr' */ |
| |
| |
| g_variant_get (value5, "(m*s)", &contents, NULL); /* ignore the string. */ |
| if (contents != NULL) |
| { |
| g_variant_get (contents, "(ii)", &x, &y); |
| g_print ("it was (%d, %d)\n", x, y); |
| g_variant_unref (contents); |
| } |
| else |
| g_print ("it was null\n"); |
| }]]></programlisting></informalexample> |
| </refsect3> |
| </refsect2> |
| |
| <refsect2 id='gvariant-format-strings-tuples'> |
| <title>Tuples</title> |
| <para> |
| <emphasis role='strong'> |
| Characters: <code>()</code> |
| </emphasis> |
| </para> |
| |
| <para> |
| Tuples are handled by handling each item in the tuple, in sequence. Each item is handled in the usual way. |
| </para> |
| |
| <refsect3> |
| <title>Examples</title> |
| <informalexample><programlisting> |
| <![CDATA[GVariant *value1, *value2; |
| |
| value1 = g_variant_new ("(s(ii))", "Hello", 55, 77); |
| value2 = g_variant_new ("()"); |
| |
| { |
| gchar *string; |
| gint x, y; |
| |
| g_variant_get (value1, "(s(ii))", &string, &x, &y); |
| g_print ("%s, %d, %d\n", string, x, y); |
| g_free (string); |
| |
| g_variant_get (value2, "()"); /* do nothing... */ |
| }]]></programlisting></informalexample> |
| </refsect3> |
| </refsect2> |
| |
| <refsect2 id='gvariant-format-strings-dictionaries'> |
| <title>Dictionaries</title> |
| <para> |
| <emphasis role='strong'> |
| Characters: <code>{}</code> |
| </emphasis> |
| </para> |
| |
| <para> |
| Dictionary entries are handled by handling first the key, then the value. Each is handled in the usual way. |
| </para> |
| |
| <refsect3> |
| <title>Examples</title> |
| <informalexample><programlisting> |
| <![CDATA[GVariantBuilder *b; |
| GVariant *dict; |
| |
| b = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); |
| g_variant_builder_add (b, "{sv}", "name", g_variant_new_string ("foo")); |
| g_variant_builder_add (b, "{sv}", "timeout", g_variant_new_int32 (10)); |
| dict = g_variant_builder_end (b);]]></programlisting></informalexample> |
| </refsect3> |
| </refsect2> |
| |
| <refsect2 id='gvariant-format-strings-gvariant'> |
| <title>GVariant *</title> |
| <para> |
| <emphasis role='strong'> |
| Characters: <literal>@</literal>, <literal>*</literal>, <literal>?</literal>, <literal>r</literal> |
| </emphasis> |
| |
| </para> |
| <para> |
| Upon encountering a '<literal>@</literal>' in front of a type string, |
| <link linkend='g-variant-new'><function>g_variant_new()</function></link> takes a |
| non-<link linkend='NULL:CAPS'><literal>NULL</literal></link> pointer to a |
| <link linkend='GVariant'><type>GVariant</type></link> and uses its value directly instead of collecting arguments to |
| create the value. The provided <link linkend='GVariant'><type>GVariant</type></link> must have a type that matches the |
| type string following the '<literal>@</literal>'. '<literal>*</literal>' is |
| the same as '<literal>@*</literal>' (ie: take a <link linkend='GVariant'><type>GVariant</type></link> of any type). |
| '<literal>?</literal>' is the same as '<literal>@?</literal>' (ie: take a |
| <link linkend='GVariant'><type>GVariant</type></link> of any basic type). '<literal>r</literal>' is the same as |
| '<literal>@r</literal>' (ie: take a <link linkend='GVariant'><type>GVariant</type></link> of any tuple type). |
| </para> |
| <para> |
| Upon encountering a '<literal>@</literal>' in front of a type string, |
| <link linkend='g-variant-get'><function>g_variant_get()</function></link> |
| takes a pointer to a <code>(<link linkend='GVariant'>GVariant</link> *)</code> (ie: a |
| <code>(<link linkend='GVariant'>GVariant</link> **)</code>) and sets it to a new reference to a |
| <link linkend='GVariant'><type>GVariant</type></link> containing the value (instead of deconstructing the value into |
| C types in the usual way). <link linkend='NULL:CAPS'><literal>NULL</literal></link> can be given to ignore the |
| value. '<literal>*</literal>', '<literal>?</literal>' and '<literal>r</literal>' are handled in a way analogous to |
| what is stated above. |
| </para> |
| <para> |
| You can always use '<literal>*</literal>' as an alternative to '<literal>?</literal>', '<literal>r</literal>' or any |
| use of '<literal>@</literal>'. Using the other characters where possible is recommended, however, due to the |
| improvements in type safety and code self-documentation. |
| </para> |
| |
| <refsect3> |
| <title>Examples</title> |
| <informalexample><programlisting> |
| <![CDATA[GVariant *value1, *value2; |
| |
| value1 = g_variant_new ("(i@ii)", 44, g_variant_new_int32 (55), 66); |
| |
| /* note: consumes floating reference count on 'value1' */ |
| value2 = g_variant_new ("(@(iii)*)", value1, g_variant_new_string ("foo")); |
| |
| { |
| const gchar *string; |
| GVariant *tmp; |
| gsize length; |
| gint x, y, z; |
| |
| g_variant_get (value2, "((iii)*)", &x, &y, &z, &tmp); |
| string = g_variant_get_string (tmp, &length); |
| g_print ("it is %d %d %d %s (length=%d)\n", x, y, z, string, (int) length); |
| g_variant_unref (tmp); |
| |
| /* quick way to skip all the values in a tuple */ |
| g_variant_get (value2, "(rs)", NULL, &string); /* or "(@(iii)s)" */ |
| g_print ("i only got the string: %s\n", string); |
| g_free (string); |
| }]]></programlisting></informalexample> |
| </refsect3> |
| </refsect2> |
| |
| <refsect2 id='gvariant-format-strings-pointers'> |
| <title>Pointers</title> |
| <para> |
| <emphasis role='strong'> |
| Characters: <code>&</code> |
| </emphasis> |
| </para> |
| |
| <para> |
| The '<code>&</code>' character is used to indicate that serialised data should be directly exchanged via a |
| pointer. |
| </para> |
| <para> |
| Currently, the only use for this character is when it is applied to a string (ie: '<literal>&s</literal>', |
| '<literal>&o</literal>' or '<code>&g</code>'). For |
| <link linkend='g-variant-new'><function>g_variant_new()</function></link> this has absolutely no effect. The string |
| is collected and duplicated normally. For <link linkend='g-variant-get'><function>g_variant_get()</function></link> |
| it means that instead of creating a newly allocated copy of the string, a pointer to the serialised data is |
| returned. This pointer should not be freed. Validity checks are performed to ensure that the string data will |
| always be properly nul-terminated. |
| </para> |
| |
| <refsect3> |
| <title>Examples</title> |
| <informalexample><programlisting> |
| <![CDATA[{ |
| const gchar *str; |
| GVariant *value; |
| |
| value = g_variant_new ("&s", "hello world"); |
| g_variant_get (value, "&s", &str); |
| g_print ("string is: %s\n", str); |
| /* no need to free str */ |
| }]]></programlisting></informalexample> |
| </refsect3> |
| </refsect2> |
| |
| <refsect2 id='gvariant-format-strings-convenience'> |
| <title>Convenience Conversions</title> |
| <para> |
| <emphasis role='strong'> |
| Characters: <literal>^</literal> |
| </emphasis> |
| </para> |
| |
| <para> |
| The '<literal>^</literal>' character currently supports conversion to and from bytestrings or to and from arrays |
| of strings or bytestrings. It has a number of forms. |
| </para> |
| |
| <para> |
| In all forms, when used with <link linkend='g-variant-new'><function>g_variant_new()</function></link> one |
| pointer value is collected from the variable arguments and passed to a function (as given in the table below). |
| The result of that function is used as the value for this position. When used with |
| <link linkend='g-variant-get'><function>g_variant_get()</function></link> one pointer value is produced by using |
| the function (given in the table) and returned by reference. |
| </para> |
| |
| <informaltable> |
| <tgroup cols='2'> |
| <colspec colname='col_0'/> |
| <colspec colname='col_1'/> |
| <colspec colname='col_2'/> |
| <tbody> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'>Conversion</emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| Used with <link linkend='g-variant-new'><function>g_variant_new()</function></link> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| Used with <link linkend='g-variant-get'><function>g_variant_get()</function></link> |
| </emphasis> |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>^as</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1' morerows='1'> |
| <para> |
| equivalent to <link linkend='g-variant-new-strv'><function>g_variant_new_strv()</function></link> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| equivalent to <link linkend='g-variant-dup-strv'><function>g_variant_dup_strv()</function></link> |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>^a&s</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| equivalent to <link linkend='g-variant-get-strv'><function>g_variant_get_strv()</function></link> |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>^ao</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1' morerows='1'> |
| <para> |
| equivalent to <link linkend='g-variant-new-objv'><function>g_variant_new_objv()</function></link> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| equivalent to <link linkend='g-variant-dup-objv'><function>g_variant_dup_objv()</function></link> |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>^a&o</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| equivalent to <link linkend='g-variant-get-objv'><function>g_variant_get_objv()</function></link> |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>^ay</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1' morerows='1'> |
| <para> |
| equivalent to <link linkend='g-variant-new-bytestring'><function>g_variant_new_bytestring()</function></link> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| equivalent to <link linkend='g-variant-dup-bytestring'><function>g_variant_dup_bytestring()</function></link> |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>^&ay</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| equivalent to <link linkend='g-variant-get-bytestring'><function>g_variant_get_bytestring()</function></link> |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>^aay</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1' morerows='1'> |
| <para> |
| equivalent to <link linkend='g-variant-new-bytestring-array'><function>g_variant_new_bytestring_array()</function></link> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| equivalent to <link linkend='g-variant-dup-bytestring-array'><function>g_variant_dup_bytestring_array()</function></link> |
| </para> |
| </entry> |
| </row> |
| |
| <row rowsep='1'> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| <emphasis role='strong'> |
| <literal>^a&ay</literal> |
| </emphasis> |
| </para> |
| </entry> |
| <entry colsep='1' rowsep='1'> |
| <para> |
| equivalent to <link linkend='g-variant-get-bytestring-array'><function>g_variant_get_bytestring_array()</function></link> |
| </para> |
| </entry> |
| </row> |
| |
| </tbody> |
| </tgroup> |
| </informaltable> |
| </refsect2> |
| </refsect1> |
| </refentry> |