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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
|
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-marshal-recursive.h Marshalling routines for recursive types
*
* Copyright (C) 2004, 2005 Red Hat, Inc.
*
* Licensed under the Academic Free License version 2.1
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef DBUS_MARSHAL_RECURSIVE_H
#define DBUS_MARSHAL_RECURSIVE_H
#include <config.h>
#include <dbus/dbus-protocol.h>
#include <dbus/dbus-list.h>
#include <dbus/dbus-marshal-basic.h> /* this can vanish when we merge */
#ifndef PACKAGE
#error "config.h not included here"
#endif
/* Features we need to port dbus-message:
* - memoize a position of a reader for small/fast access later
* - delete an array element and re-align the remainder of the array
* (not necessary yet to re-align remainder of entire string,
* though that's probably just as hard/easy)
* (really this one is to set a complex-type array element to
* a new value, but for dbus-message.c delete-and-reappend would
* be good enough)
* - set string, int, etc. values at a memoized position
* (implement generic set of any value? changes only
* value_str not type_str)
* - implement has_next()
* - the all-in-one-block array accessors
* - validation
*
* - remember to try a HAVE_INT64=0 build at the end
*/
typedef struct DBusTypeMark DBusTypeMark;
typedef struct DBusTypeReader DBusTypeReader;
typedef struct DBusTypeWriter DBusTypeWriter;
typedef struct DBusTypeReaderClass DBusTypeReaderClass;
typedef struct DBusArrayLenFixup DBusArrayLenFixup;
/** The mark is a way to compress a #DBusTypeReader; it isn't all that
* successful though. The idea was to use this for caching header
* fields in dbus-message.c. However now I'm thinking why not cache
* the actual values (e.g. char*) and if the field needs to be set or
* deleted, just linear search for it. Those operations are uncommon,
* and getting the values should be fast and not involve all this type
* reader nonsense.
*
* @todo DBusTypeMark isn't used right now and probably won't be, we should delete it
*/
struct DBusTypeMark
{
dbus_uint32_t type_pos_in_value_str : 1; /**< true if the type_pos is in value_str and not type_str */
dbus_uint32_t container_type : 3; /**< the "id" of the container type */
dbus_uint32_t array_len_offset : 3; /**< bytes back from start_pos that len ends */
dbus_uint32_t type_pos : DBUS_MAXIMUM_MESSAGE_LENGTH_BITS; /**< position in type_str */
dbus_uint32_t value_pos : DBUS_MAXIMUM_MESSAGE_LENGTH_BITS; /**< position in value_str */
dbus_uint32_t array_start_pos : DBUS_MAXIMUM_MESSAGE_LENGTH_BITS; /**< start of the array the reader was iterating over */
};
/**
* The type reader is an iterator for reading values from a block of
* values.
*/
struct DBusTypeReader
{
dbus_uint32_t byte_order : 8; /**< byte order of the block */
dbus_uint32_t finished : 1; /**< marks we're at end iterator for cases
* where we don't have another way to tell
*/
dbus_uint32_t array_len_offset : 3; /**< bytes back from start_pos that len ends */
const DBusString *type_str; /**< string containing signature of block */
int type_pos; /**< current position in signature */
const DBusString *value_str; /**< string containing values of block */
int value_pos; /**< current position in values */
const DBusTypeReaderClass *klass; /**< the vtable for the reader */
union
{
struct {
int start_pos; /**< for array readers, the start of the array values */
} array;
} u; /**< class-specific data */
};
/**
* The type writer is an iterator for writing to a block of values.
*/
struct DBusTypeWriter
{
dbus_uint32_t byte_order : 8; /**< byte order to write values with */
dbus_uint32_t container_type : 8; /**< what are we inside? (e.g. struct, variant, array) */
dbus_uint32_t type_pos_is_expectation : 1; /**< type_pos can be either an insertion point for or an expected next type */
dbus_uint32_t enabled : 1; /**< whether to write values */
DBusString *type_str; /**< where to write typecodes (or read type expectations) */
int type_pos; /**< current pos in type_str */
DBusString *value_str; /**< where to write values */
int value_pos; /**< next position to write */
union
{
struct {
int start_pos; /**< position of first element in the array */
int len_pos; /**< position of length of the array */
int element_type_pos; /**< position of array element type in type_str */
} array;
} u; /**< class-specific data */
};
/**
* When modifying an existing block of values, array lengths may need
* to be adjusted; those adjustments are described by this struct.
*/
struct DBusArrayLenFixup
{
int len_pos_in_reader; /**< where the length was in the original block */
int new_len; /**< the new value of the length in the written-out block */
};
void _dbus_type_reader_init (DBusTypeReader *reader,
int byte_order,
const DBusString *type_str,
int type_pos,
const DBusString *value_str,
int value_pos);
void _dbus_type_reader_init_from_mark (DBusTypeReader *reader,
int byte_order,
const DBusString *type_str,
const DBusString *value_str,
const DBusTypeMark *mark);
void _dbus_type_reader_init_types_only (DBusTypeReader *reader,
const DBusString *type_str,
int type_pos);
void _dbus_type_reader_init_types_only_from_mark (DBusTypeReader *reader,
const DBusString *type_str,
const DBusTypeMark *mark);
void _dbus_type_reader_save_mark (const DBusTypeReader *reader,
DBusTypeMark *mark);
int _dbus_type_reader_get_current_type (const DBusTypeReader *reader);
int _dbus_type_reader_get_element_type (const DBusTypeReader *reader);
int _dbus_type_reader_get_value_pos (const DBusTypeReader *reader);
void _dbus_type_reader_read_basic (const DBusTypeReader *reader,
void *value);
void _dbus_type_reader_read_fixed_multi (const DBusTypeReader *reader,
void *value,
int *n_elements);
void _dbus_type_reader_read_raw (const DBusTypeReader *reader,
const unsigned char **value_location);
void _dbus_type_reader_recurse (DBusTypeReader *reader,
DBusTypeReader *subreader);
dbus_bool_t _dbus_type_reader_next (DBusTypeReader *reader);
dbus_bool_t _dbus_type_reader_has_next (const DBusTypeReader *reader);
void _dbus_type_reader_get_signature (const DBusTypeReader *reader,
const DBusString **str_p,
int *start_p,
int *len_p);
dbus_bool_t _dbus_type_reader_set_basic (DBusTypeReader *reader,
const void *value,
const DBusTypeReader *realign_root);
dbus_bool_t _dbus_type_reader_delete (DBusTypeReader *reader,
const DBusTypeReader *realign_root);
dbus_bool_t _dbus_type_reader_greater_than (const DBusTypeReader *lhs,
const DBusTypeReader *rhs);
void _dbus_type_writer_init (DBusTypeWriter *writer,
int byte_order,
DBusString *type_str,
int type_pos,
DBusString *value_str,
int value_pos);
void _dbus_type_writer_init_types_delayed (DBusTypeWriter *writer,
int byte_order,
DBusString *value_str,
int value_pos);
void _dbus_type_writer_add_types (DBusTypeWriter *writer,
DBusString *type_str,
int type_pos);
void _dbus_type_writer_remove_types (DBusTypeWriter *writer);
void _dbus_type_writer_init_values_only (DBusTypeWriter *writer,
int byte_order,
const DBusString *type_str,
int type_pos,
DBusString *value_str,
int value_pos);
dbus_bool_t _dbus_type_writer_write_basic (DBusTypeWriter *writer,
int type,
const void *value);
dbus_bool_t _dbus_type_writer_write_fixed_multi (DBusTypeWriter *writer,
int element_type,
const void *value,
int n_elements);
dbus_bool_t _dbus_type_writer_recurse (DBusTypeWriter *writer,
int container_type,
const DBusString *contained_type,
int contained_type_start,
DBusTypeWriter *sub);
dbus_bool_t _dbus_type_writer_unrecurse (DBusTypeWriter *writer,
DBusTypeWriter *sub);
dbus_bool_t _dbus_type_writer_append_array (DBusTypeWriter *writer,
const DBusString *contained_type,
int contained_type_start,
DBusTypeWriter *sub);
dbus_bool_t _dbus_type_writer_write_reader (DBusTypeWriter *writer,
DBusTypeReader *reader);
dbus_bool_t _dbus_type_writer_write_reader_partial (DBusTypeWriter *writer,
DBusTypeReader *reader,
const DBusTypeReader *start_after,
int start_after_new_pos,
int start_after_new_len,
DBusList **fixups);
void _dbus_type_writer_set_enabled (DBusTypeWriter *writer,
dbus_bool_t enabled);
#endif /* DBUS_MARSHAL_RECURSIVE_H */
|