[glib/gvariant] add gvariant format string documentation



commit 20314907f230d3fcb2d5a71dc63121979fe61dae
Author: Ryan Lortie <desrt desrt ca>
Date:   Thu Jan 14 15:52:25 2010 -0500

    add gvariant format string documentation

 docs/reference/glib/glib-docs.sgml       |    2 +
 docs/reference/glib/gvariant-varargs.xml | 1025 ++++++++++++++++++++++++++++++
 2 files changed, 1027 insertions(+), 0 deletions(-)
---
diff --git a/docs/reference/glib/glib-docs.sgml b/docs/reference/glib/glib-docs.sgml
index 2e84b9e..83496f5 100644
--- a/docs/reference/glib/glib-docs.sgml
+++ b/docs/reference/glib/glib-docs.sgml
@@ -82,6 +82,7 @@
 <!ENTITY glib-gettextize SYSTEM "glib-gettextize.xml">
 <!ENTITY gtester SYSTEM "gtester.xml">
 <!ENTITY gtester-report SYSTEM "gtester-report.xml">
+<!ENTITY gvariant-varargs SYSTEM "gvariant-varargs.xml">
 
 <!ENTITY version SYSTEM "version.xml">
 ]>
@@ -203,6 +204,7 @@ synchronize their operation.
     &glib-Memory-Allocators;
     &glib-GVariantType;
     &glib-GVariant;
+    &gvariant-varargs;
   </chapter>
 
   <chapter id="tools">
diff --git a/docs/reference/glib/gvariant-varargs.xml b/docs/reference/glib/gvariant-varargs.xml
new file mode 100644
index 0000000..f4217e1
--- /dev/null
+++ b/docs/reference/glib/gvariant-varargs.xml
@@ -0,0 +1,1025 @@
+<?xml version='1.0' encoding='utf-8'?>
+
+<refentry id='gvariant-varargs'>
+ <refentrytitle>GVariant Format Strings</refentrytitle>
+
+ <refsect1>
+  <title>Variable Argument Conversions</title>
+
+  <para>
+   This page attempts to document how to perform variable argument conversions with GVariant. 
+  </para>
+  <para>
+   A conversion 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>
+     a type string of a concrete, fixed-sized type, prefixed with a '<literal>&amp;</literal>' 
+    </para>
+   </listitem>
+   <listitem>
+    <para>
+     a type string of a concrete, fixed-sized type, prefixed with a '<literal>&amp;a</literal>' 
+    </para>
+   </listitem>
+   <listitem>
+    <para>
+     '<literal>&amp;s</literal>' '<literal>&amp;o</literal>', '<literal>&amp;g</literal>', '<literal>^as</literal>',
+     '<literal>^ao</literal>', '<literal>^ag</literal>', '<literal>^a&amp;s</literal>', '<literal>^a&amp;o</literal>' or
+     '<literal>^a&amp;g</literal>'
+    </para>
+   </listitem>
+   <listitem>
+    <para>
+     any conversion string, prefixed with an '<literal>m</literal>' 
+    </para>
+   </listitem>
+   <listitem>
+    <para>
+     a sequence of zero or more format strings 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-variant'>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-nullable-types'>Nullable 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 on a GVariant type string (not format string).  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>.  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>&amp;</literal></emphasis>
+       </para>
+      </entry>
+      <entry colsep='1' rowsep='1'>
+       <para>
+        Used as a prefix on a GVariant type string (not format string).  Denotes that a C pointer to serialised data
+        should be used in place of the normal C type or types.  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>
+
+   <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 suported.  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.  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
+    <link linkend='GVariantIter'><type>GVariantIter</type></link> (ie:
+    <code>(<link linkend='GVariantIter'>GVariantIter</link> *)</code>).  The iter (which is assumed to be completely
+    uninitialised) is initialised for iterating over the elements of the array.
+    <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_CLASS_ARRAY, NULL);
+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);
+
+{
+  GVariantIter iter;
+  gchar *str;
+
+  g_variant_get (value, "as", &iter);
+  while (g_variant_iter_next (&iter, "s", &str))
+    g_print ("%s\n");
+}]]></programlisting></informalexample>
+   </refsect3>
+  </refsect2>
+
+  <refsect2 id='gvariant-format-strings-nullable-types'>
+   <title>Nullable Types</title>
+   <para>
+    <emphasis role='strong'>
+     Characters: <literal>m</literal>
+    </emphasis>
+   </para>
+   <para>
+    Nullable types are handled in two separate ways depending on the format string that follows the
+    '<literal>m</literal>'.  The method that is used always depends entirely on the character immediately following the
+    '<literal>m</literal>'.
+   </para>
+
+   <para>
+    The first way is used with format strings starting with '<literal>s</literal>', '<literal>o</literal>',
+    '<literal>g</literal>', '<literal>v</literal>', '<literal>@</literal>', '<literal>*</literal>',
+    '<literal>?</literal>', '<literal>r</literal>', '<literal>&amp;</literal>', or '<literal>^</literal>'.  In all of
+    these cases, for non-nullable 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.  If the format string
+    normally involves taking of other arguments (such as an integer for the length of an array) then those values are
+    still taken as normal, but in the <link linkend='NULL--CAPS'><literal>NULL</literal></link> case, they are ignored.
+   </para>
+   <para>
+    The second way is used with all other format strings.  For both
+    <link linkend='g-variant-new'><function>g_variant_new()</function></link> and
+    <link linkend='g-variant-get'><function>g_variant_get()</function></link> an additional
+    <code>(<link linkend='gboolean'>gboolean</link> *)</code> argument is collected.  If
+    <link linkend='NULL--CAPS'><literal>NULL</literal></link> is given then no further arguments will be collected for the
+    format string.  If a non-<link linkend='NULL--CAPS'><literal>NULL</literal></link> value is given then the arguments
+    that are normally collected for the equivalent non-nullable type will be collected following the
+    <code>(<link linkend='gboolean'>gboolean</link> *)</code>.
+   </para>
+   <para>
+    If <link linkend='NULL--CAPS'><literal>NULL</literal></link>, or a pointer to 
+    <link linkend='FALSE--CAPS'><literal>FALSE</literal></link> is given to
+    <link linkend='g-variant-new'><function>g_variant_new()</function></link> then the null value is constructed.  In
+    the case that the arguments were collected, they will be ignored.  Otherwise (if a pointer to
+    <link linkend='TRUE--CAPS'><literal>TRUE</literal></link> was given), the arguments are used in the normal way to
+    create the non-null 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 non-null.  In the case that the value was non-null, 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 null, 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 they values that they point to will be ignored. 
+   </para>
+   <para>
+    The macro <link linkend='G-VARIANT-JUST--CAPS'><literal>G_VARIANT_JUST</literal></link> is provided.  It evaluates
+    to a pointer to a <link linkend='gboolean'><type>gboolean</type></link> containing
+    <link linkend='TRUE--CAPS'><literal>TRUE</literal></link>.
+   </para>
+
+   <refsect3>
+    <title>Examples</title>
+    <informalexample><programlisting>
+<![CDATA[GVariant *value1, *value2, *value3, *value4, *value5, *value6;
+gboolean f = FALSE;
+
+value1 = g_variant_new ("ms", "Hello world");
+value2 = g_variant_new ("ms", NULL);
+value3 = g_variant_new ("(m(ii)s)", G_VARIANT_JUST, 123, 456, "Done");
+value4 = g_variant_new ("(m(ii)s)", &f, -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 *, so 'gint32 *' not collected */
+  g_variant_get (value3, "(m(ii)s)", NULL, &str); /* only interested in the string. */
+  g_print ("string is %s\n", str);
+  g_free (str);
+
+
+  /* non-NULL passed for gboolean *, so 2 'gint32 *' are collected */
+  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_CLASS_ARRAY, 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>&amp;</code>
+    </emphasis>
+   </para>
+
+   <para>
+    The '<code>&amp;</code>' character has 3 closely-related uses.  In all cases, when used with
+    <link linkend='g-variant-get'><function>g_variant_get()</function></link> it means that a pointer directly to the
+    serialised data stored inside the GVariant is returned (either directly or indirectly).  This pointer is valid only
+    for as long as the GVariant exists. 
+   </para>
+   <para>
+    The three cases are as follows:
+   </para>
+   <para>
+    The simplest case is when it is applied to a string (ie: '<literal>&amp;s</literal>', '<literal>&amp;o</literal>' or
+    '<code>&amp;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>
+   <para>
+    The next case is when '<literal>&amp;</literal>' is used to prefix a type string corresponding to a fixed-size type
+    (ie: a type whose values are always the same size).  This includes booleans, bytes, integers, doubles and tuples or
+    dictionary entries consisting entirely of those types (recursively).  Arrays, nullable types, strings, variants and
+    tuples or dictionaries containing those types are not fixed-size types.  In this case, instead of collecting the
+    arguments in the usual way, a single pointer is collected.
+    <link linkend='g-variant-new'><function>g_variant_new()</function></link> collects a pointer to the data as it would
+    appear in serialised form and makes a copy.
+    <link linkend='g-variant-get'><function>g_variant_get()</function></link> collects a pointer to a
+    <link linkend='gpointer'><type>gpointer</type></link> and sets it to point to the serialised data.  In the
+    <link linkend='g-variant-get'><function>g_variant_get()</function></link> case,
+    <link linkend='NULL--CAPS'><literal>NULL</literal></link> may be given to ignore the value. 
+   </para>
+   <para>
+    The last case is when '<literal>&amp;a</literal>' is used to prefix a type string corresponding to a fixed-size type
+    (ie: an array in which each item has a fixed size).  In this case, in addition to collecting the pointer to the data
+    itself, <link linkend='g-variant-new'><function>g_variant_new()</function></link> collects a
+    <link linkend='gsize'><type>gsize</type></link> and
+    <link linkend='g-variant-get'><function>g_variant_get()</function></link> collects a
+    <code>(<link linkend='gsize'>gsize</link> *)</code>.  These are the length of the array; not its size in bytes.
+   </para>
+   <para>
+    <emphasis role='string'>Note:</emphasis> even though it will work on 32bit platforms, an
+    <link linkend='gint'><type>int</type></link> is not normally the same thing as a
+    <link linkend='gsize'><type>gsize</type></link>.  This means that passing an
+    <link linkend='gint'><type>int</type></link> (including integer literals) as the size of an array is not correct and
+    will cause problems on 64bit platforms.  Always cast to <link linkend='gsize'><type>gsize</type></link> first, or
+    better yet, use <link linkend='G-N-ELEMENTS--CAPS'><function>G_N_ELEMENTS()</function></link> (which returns
+    <link linkend='gsize'><type>gsize</type></link>).
+   </para>
+
+   <refsect3>
+    <title>Examples</title>
+    <informalexample><programlisting>
+<![CDATA[struct {
+  gint32 x, y;
+} struc = {
+  11, 22
+};
+GVariant *value1, *value2, *value3;
+gint32 array[] = { 33, 44, 55 };
+
+value1 = g_variant_new ("&ai", array, G_N_ELEMENTS (array));
+value2 = g_variant_new_string ("hello world");
+value3 = g_variant_new ("&(ii)", &struc);]]></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 only has one purpose: to convert to and from
+    <link linkend='G-TYPE-STRV'><literal>G_TYPE_STRV</literal></link> type arrays of strings.  It is always used with
+    arrays of strings (or other string types).  It has two forms. 
+   </para>
+   <itemizedlist>
+    <listitem>
+     <para>
+      '<literal>^as</literal>' (or <literal>o</literal> or <literal>g</literal>) 
+     </para>
+    </listitem>
+    <listitem>
+     <para>
+      '<literal>^a&amp;s</literal>' (or <literal>o</literal> or <literal>g</literal>) 
+     </para>
+    </listitem>
+   </itemizedlist>
+   <para>
+    When used with <link linkend='g-variant-new'><function>g_variant_new()</function></link> both forms are equivalent.
+    A <code>(const <link linkend='gchar'>gchar</link> * const *)</code> is collected.  This must be a pointer to the
+    array of <link linkend='NULL--CAPS'><literal>NULL</literal></link>-terminated pointers to strings.  This array is
+    converted to a <link linkend='GVariant'><type>GVariant</type></link> instance.  Copies are made, so the original
+    array may be freed immediately.
+   </para>
+   <para>
+    When used with <link linkend='g-variant-get'><function>g_variant_get()</function></link> the two forms have
+    different meaning.  Both return a freshly allocated
+    <link linkend='NULL--CAPS'><literal>NULL</literal></link>-terminated array of pointers to strings.  In the case of
+    '<literal>^as</literal>', the strings are owned by the caller -- it is appropriate to free the array with
+    <link linkend='g-strfreev'><function>g_strfreev()</function></link>.  In the case of '<literal>^a&amp;s</literal>',
+    a shallow copy is made; the strings themselves are embedded in the serialised data and owned by the original
+    <link linkend='GVariant'><type>GVariant</type></link> instance -- it is only appropriate to free the outer array
+    with <link linkend='g-free'><function>g_free()</function></link>. 
+   </para>
+  </refsect2>
+ </refsect1>
+</refentry>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]