summaryrefslogtreecommitdiff
path: root/glib/glib/gvarianttypeinfo.h
diff options
context:
space:
mode:
Diffstat (limited to 'glib/glib/gvarianttypeinfo.h')
-rw-r--r--glib/glib/gvarianttypeinfo.h151
1 files changed, 151 insertions, 0 deletions
diff --git a/glib/glib/gvarianttypeinfo.h b/glib/glib/gvarianttypeinfo.h
new file mode 100644
index 0000000..aaf14f4
--- /dev/null
+++ b/glib/glib/gvarianttypeinfo.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright © 2008 Ryan Lortie
+ * Copyright © 2010 Codethink Limited
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#ifndef __G_VARIANT_TYPE_INFO_H__
+#define __G_VARIANT_TYPE_INFO_H__
+
+#include <glib/gvarianttype.h>
+
+#define G_VARIANT_TYPE_INFO_CHAR_MAYBE 'm'
+#define G_VARIANT_TYPE_INFO_CHAR_ARRAY 'a'
+#define G_VARIANT_TYPE_INFO_CHAR_TUPLE '('
+#define G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY '{'
+#define G_VARIANT_TYPE_INFO_CHAR_VARIANT 'v'
+#define g_variant_type_info_get_type_char(info) \
+ (g_variant_type_info_get_type_string(info)[0])
+
+typedef struct _GVariantTypeInfo GVariantTypeInfo;
+
+/* < private >
+ * GVariantMemberInfo:
+ *
+ * This structure describes how to construct a GVariant instance
+ * corresponding to a given child of a tuple or dictionary entry in a
+ * very short constant time. It contains the typeinfo of the child,
+ * along with 4 constants that allow the bounds of the child's
+ * serialised data within the container's serialised data to be found
+ * very efficiently.
+ *
+ * Since dictionary entries are serialised as if they were tuples of 2
+ * items, the term "tuple" will be used here in the general sense to
+ * refer to tuples and dictionary entries.
+ *
+ * BACKGROUND:
+ * The serialised data for a tuple contains an array of "offsets" at
+ * the end. There is one "offset" in this array for each
+ * variable-sized item in the tuple (except for the last one). The
+ * offset points to the end point of that item's serialised data. The
+ * procedure for finding the start point is described below. An
+ * offset is not needed for the last item because the end point of the
+ * last item is merely the end point of the container itself (after
+ * the offsets array has been accounted for). An offset is not needed
+ * for fixed-sized items (like integers) because, due to their fixed
+ * size, the end point is a constant addition to the start point.
+ *
+ * It is clear that the starting point of a given item in the tuple is
+ * determined by the items that precede it in the tuple. Logically,
+ * the start point of a particular item in a given type of tuple can
+ * be determined entirely by the end point of the nearest
+ * variable-sized item that came before it (or from the start of the
+ * container itself in case there is no preceding variable-sized
+ * item). In the case of "(isis)" for example, in order to find out
+ * the start point of the last string, one must start at the end point
+ * of the first string, align to 4 (for the integer's alignment) and
+ * then add 4 (for storing the integer). That's the point where the
+ * string starts (since no special alignment is required for strings).
+ *
+ * Of course, this process requires iterating over the types in the
+ * tuple up to the item of interest. As it turns out, it is possible
+ * to determine 3 constants 'a', 'b', and 'c' for each item in the
+ * tuple, such that, given the ending offset of the nearest previous
+ * variable-sized item (prev_end), a very simple calculation can be
+ * performed to determine the start of the item of interest.
+ *
+ * The constants in this structure are used as follows:
+ *
+ * First, among the array of offets contained in the tuple, 'i' is the
+ * index of the offset that refers to the end of the variable-sized item
+ * preceding the item of interest. If no variable-sized items precede
+ * this item, then 'i' will be -1.
+ *
+ * Let 'prev_end' be the end offset of the previous item (or 0 in the
+ * case that there was no such item). The start address of this item
+ * can then be calculate using 'a', 'b', and 'c':
+ *
+ * item_start = ((prev_end + a) & b) | c;
+ *
+ * For details about how 'a', 'b' and 'c' are calculated, see the
+ * comments at the point of the implementation in gvariantypeinfo.c.
+ *
+ * The end address of the item is then determined in one of three ways,
+ * according to the 'end_type' field.
+ *
+ * - FIXED: For fixed sized items, the end address is equal to the
+ * start address plus the fixed size.
+ *
+ * - LAST: For the last variable sized item in the tuple, the end
+ * address is equal to the end address of the tuple, minus the size
+ * of the offset array.
+ *
+ * - OFFSET: For other variable sized items, the next index past 'i'
+ * (ie: 'i + 1') must be consulted to find the end of this item.
+ */
+
+typedef struct
+{
+ GVariantTypeInfo *type_info;
+
+ gsize i, a;
+ gint8 b, c;
+
+ guint8 ending_type;
+} GVariantMemberInfo;
+
+#define G_VARIANT_MEMBER_ENDING_FIXED 0
+#define G_VARIANT_MEMBER_ENDING_LAST 1
+#define G_VARIANT_MEMBER_ENDING_OFFSET 2
+
+/* query */
+const gchar * g_variant_type_info_get_type_string (GVariantTypeInfo *typeinfo);
+
+void g_variant_type_info_query (GVariantTypeInfo *typeinfo,
+ guint *alignment,
+ gsize *size);
+
+/* array */
+GVariantTypeInfo * g_variant_type_info_element (GVariantTypeInfo *typeinfo);
+void g_variant_type_info_query_element (GVariantTypeInfo *typeinfo,
+ guint *alignment,
+ gsize *size);
+
+/* structure */
+gsize g_variant_type_info_n_members (GVariantTypeInfo *typeinfo);
+const GVariantMemberInfo * g_variant_type_info_member_info (GVariantTypeInfo *typeinfo,
+ gsize index);
+
+/* new/ref/unref */
+GVariantTypeInfo * g_variant_type_info_get (const GVariantType *type);
+GVariantTypeInfo * g_variant_type_info_ref (GVariantTypeInfo *typeinfo);
+void g_variant_type_info_unref (GVariantTypeInfo *typeinfo);
+void g_variant_type_info_assert_no_infos (void);
+
+#endif /* __G_VARIANT_TYPE_INFO_H__ */