File: gvarianttypeinfo.h

package info (click to toggle)
glib2.0 2.58.3-2+deb10u2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, buster-backports, sid
  • size: 48,956 kB
  • sloc: ansic: 452,656; xml: 16,781; python: 6,149; makefile: 3,776; sh: 1,499; perl: 1,140; cpp: 9
file content (161 lines) | stat: -rw-r--r-- 7,235 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
 * 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.1 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, see <http://www.gnu.org/licenses/>.
 *
 * 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 */
GLIB_AVAILABLE_IN_ALL
const gchar *                   g_variant_type_info_get_type_string     (GVariantTypeInfo   *typeinfo);

GLIB_AVAILABLE_IN_ALL
void                            g_variant_type_info_query               (GVariantTypeInfo   *typeinfo,
                                                                         guint              *alignment,
                                                                         gsize              *size);
GLIB_AVAILABLE_IN_2_58
gsize                           g_variant_type_info_query_depth         (GVariantTypeInfo   *typeinfo);

/* array */
GLIB_AVAILABLE_IN_ALL
GVariantTypeInfo *              g_variant_type_info_element             (GVariantTypeInfo   *typeinfo);
GLIB_AVAILABLE_IN_ALL
void                            g_variant_type_info_query_element       (GVariantTypeInfo   *typeinfo,
                                                                         guint              *alignment,
                                                                         gsize              *size);

/* structure */
GLIB_AVAILABLE_IN_ALL
gsize                           g_variant_type_info_n_members           (GVariantTypeInfo   *typeinfo);
GLIB_AVAILABLE_IN_ALL
const GVariantMemberInfo *      g_variant_type_info_member_info         (GVariantTypeInfo   *typeinfo,
                                                                         gsize               index);

/* new/ref/unref */
GLIB_AVAILABLE_IN_ALL
GVariantTypeInfo *              g_variant_type_info_get                 (const GVariantType *type);
GLIB_AVAILABLE_IN_ALL
GVariantTypeInfo *              g_variant_type_info_ref                 (GVariantTypeInfo   *typeinfo);
GLIB_AVAILABLE_IN_ALL
void                            g_variant_type_info_unref               (GVariantTypeInfo   *typeinfo);
GLIB_AVAILABLE_IN_ALL
void                            g_variant_type_info_assert_no_infos     (void);

#endif /* __G_VARIANT_TYPE_INFO_H__ */