index.html
Main Page
|
modules.html
Modules
|
namespaces.html
Namespace List
|
hierarchy.html
Class Hierarchy
|
annotated.html
Data Structures
|
dirs.html
Directories
|
files.html
File List
|
namespacemembers.html
Namespace Members
|
functions.html
Data Fields
|
pages.html
Related Pages
dir_000004.html
dbus
dbus-marshal-recursive.c
00001
/* -*- mode: C; c-file-style: "gnu" -*- */
00002
/* dbus-marshal-recursive.c  Marshalling routines for recursive types
00003
*
00004
* Copyright (C) 2004, 2005 Red Hat, Inc.
00005
*
00006
* Licensed under the Academic Free License version 2.1
00007
*
00008
* This program is free software; you can redistribute it and/or modify
00009
* it under the terms of the GNU General Public License as published by
00010
* the Free Software Foundation; either version 2 of the License, or
00011
* (at your option) any later version.
00012
*
00013
* This program is distributed in the hope that it will be useful,
00014
* but WITHOUT ANY WARRANTY; without even the implied warranty of
00015
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016
* GNU General Public License for more details.
00017
*
00018
* You should have received a copy of the GNU General Public License
00019
* along with this program; if not, write to the Free Software
00020
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021
*
00022
*/
00023
00024
#include "dbus-marshal-recursive.h"
00025
#include "dbus-marshal-basic.h"
00026
#include "dbus-signature.h"
00027
#include "dbus-internals.h"
00028
group__DBusMarshal.html#ga181
00035
#define RECURSIVE_MARSHAL_READ_TRACE  0
00036
group__DBusMarshal.html#ga182
00038
#define RECURSIVE_MARSHAL_WRITE_TRACE 0
00039
00040
static
void
00041 free_fixups (
structDBusList.html
DBusList
**fixups)
00042 {
00043
structDBusList.html
DBusList
*link;
00044
00045   link =
group__DBusList.html#ga13
_dbus_list_get_first_link
(fixups);
00046
while
(link !=
group__DBusMacros.html#ga4
NULL
)
00047     {
00048
structDBusList.html
DBusList
*next;
00049
00050       next =
group__DBusList.html#ga24
_dbus_list_get_next_link
(fixups, link);
00051
00052
group__DBusMemory.html#ga3
dbus_free
(link->
structDBusList.html#o2
data
);
00053
group__DBusList.html#ga1
_dbus_list_free_link
(link);
00054
00055       link = next;
00056     }
00057
00058   *fixups =
group__DBusMacros.html#ga4
NULL
;
00059 }
00060
00061
static
void
00062 apply_and_free_fixups (
structDBusList.html
DBusList
**fixups,
00063
structDBusTypeReader.html
DBusTypeReader
*reader)
00064 {
00065
structDBusList.html
DBusList
*link;
00066
00067
#if RECURSIVE_MARSHAL_WRITE_TRACE
00068
if
(*fixups)
00069     _dbus_verbose (
" %d FIXUPS to apply\n"
,
00070
group__DBusList.html#ga21
_dbus_list_get_length
(fixups));
00071
#endif
00072
00073   link =
group__DBusList.html#ga13
_dbus_list_get_first_link
(fixups);
00074
while
(link !=
group__DBusMacros.html#ga4
NULL
)
00075     {
00076
structDBusList.html
DBusList
*next;
00077
00078       next =
group__DBusList.html#ga24
_dbus_list_get_next_link
(fixups, link);
00079
00080
if
(reader)
00081         {
00082
structDBusArrayLenFixup.html
DBusArrayLenFixup
*f;
00083
00084           f = link->
structDBusList.html#o2
data
;
00085
00086
#if RECURSIVE_MARSHAL_WRITE_TRACE
00087
_dbus_verbose (
" applying FIXUP to reader %p at pos %d new_len = %d old len %d\n"
,
00088                          reader, f->
structDBusArrayLenFixup.html#o0
len_pos_in_reader
, f->
structDBusArrayLenFixup.html#o1
new_len
,
00089
group__DBusMarshal.html#ga23
_dbus_marshal_read_uint32
(reader->
structDBusTypeReader.html#o5
value_str
,
00090                                                     f->
structDBusArrayLenFixup.html#o0
len_pos_in_reader
,
00091                                                     reader->
structDBusTypeReader.html#o0
byte_order
,
group__DBusMacros.html#ga4
NULL
));
00092
#endif
00093
00094
group__DBusMarshal.html#ga19
_dbus_marshal_set_uint32
((
structDBusString.html
DBusString
*) reader->
structDBusTypeReader.html#o5
value_str
,
00095                                     f->
structDBusArrayLenFixup.html#o0
len_pos_in_reader
,
00096                                     f->
structDBusArrayLenFixup.html#o1
new_len
,
00097                                     reader->
structDBusTypeReader.html#o0
byte_order
);
00098         }
00099
00100
group__DBusMemory.html#ga3
dbus_free
(link->
structDBusList.html#o2
data
);
00101
group__DBusList.html#ga1
_dbus_list_free_link
(link);
00102
00103       link = next;
00104     }
00105
00106   *fixups =
group__DBusMacros.html#ga4
NULL
;
00107 }
00108
structDBusTypeReaderClass.html
00112
struct
structDBusTypeReaderClass.html
DBusTypeReaderClass
00113 {
structDBusTypeReaderClass.html#o0
00114
const
char
*
structDBusTypeReaderClass.html#o0
name
;
structDBusTypeReaderClass.html#o1
00115
int
structDBusTypeReaderClass.html#o1
id
;
structDBusTypeReaderClass.html#o2
00116
group__DBusTypes.html#ga2
dbus_bool_t
structDBusTypeReaderClass.html#o2
types_only
;
00117   void        (*
structDBusTypeReaderClass.html#o3
recurse
)          (
structDBusTypeReader.html
DBusTypeReader
*sub,
00118
structDBusTypeReader.html
DBusTypeReader
*parent);
00119
group__DBusTypes.html#ga2
dbus_bool_t
(*
structDBusTypeReaderClass.html#o4
check_finished
)   (
const
structDBusTypeReader.html
DBusTypeReader
*reader);
00120   void        (* next)             (
structDBusTypeReader.html
DBusTypeReader
*reader,
00121
int
current_type);
00122   void        (*
structDBusTypeReaderClass.html#o6
init_from_mark
)   (
structDBusTypeReader.html
DBusTypeReader
*reader,
00123
const
structDBusTypeMark.html
DBusTypeMark
*mark);
00124 };
00125
00126
static
int
00127 element_type_get_alignment (
const
structDBusString.html
DBusString
*str,
00128
int
pos)
00129 {
00130
return
group__DBusMarshal.html#ga40
_dbus_type_get_alignment
(
group__DBusMarshal.html#ga46
_dbus_first_type_in_signature
(str, pos));
00131 }
00132
00133
static
void
00134 reader_init (
structDBusTypeReader.html
DBusTypeReader
*reader,
00135
int
byte_order,
00136
const
structDBusString.html
DBusString
*type_str,
00137
int
type_pos,
00138
const
structDBusString.html
DBusString
*value_str,
00139
int
value_pos)
00140 {
00141   reader->
structDBusTypeReader.html#o0
byte_order
= byte_order;
00142   reader->
structDBusTypeReader.html#o1
finished
=
group__DBusMacros.html#ga3
FALSE
;
00143   reader->
structDBusTypeReader.html#o3
type_str
= type_str;
00144   reader->
structDBusTypeReader.html#o4
type_pos
= type_pos;
00145   reader->
structDBusTypeReader.html#o5
value_str
= value_str;
00146   reader->
structDBusTypeReader.html#o6
value_pos
= value_pos;
00147 }
00148
00149
static
void
00150 base_reader_recurse (
structDBusTypeReader.html
DBusTypeReader
*sub,
00151
structDBusTypeReader.html
DBusTypeReader
*parent)
00152 {
00153
/* point subreader at the same place as parent */
00154   reader_init (sub,
00155                parent->
structDBusTypeReader.html#o0
byte_order
,
00156                parent->
structDBusTypeReader.html#o3
type_str
,
00157                parent->
structDBusTypeReader.html#o4
type_pos
,
00158                parent->
structDBusTypeReader.html#o5
value_str
,
00159                parent->
structDBusTypeReader.html#o6
value_pos
);
00160 }
00161
00162
static
void
00163 struct_or_dict_entry_types_only_reader_recurse (
structDBusTypeReader.html
DBusTypeReader
*sub,
00164
structDBusTypeReader.html
DBusTypeReader
*parent)
00165 {
00166   base_reader_recurse (sub, parent);
00167
00168
group__DBusInternalsUtils.html#ga130
_dbus_assert
(_dbus_string_get_byte (sub->
structDBusTypeReader.html#o3
type_str
,
00169                                        sub->
structDBusTypeReader.html#o4
type_pos
) == DBUS_STRUCT_BEGIN_CHAR ||
00170                 _dbus_string_get_byte (sub->
structDBusTypeReader.html#o3
type_str
,
00171                                        sub->
structDBusTypeReader.html#o4
type_pos
) == DBUS_DICT_ENTRY_BEGIN_CHAR);
00172
00173   sub->
structDBusTypeReader.html#o4
type_pos
+= 1;
00174 }
00175
00176
static
void
00177 struct_or_dict_entry_reader_recurse (
structDBusTypeReader.html
DBusTypeReader
*sub,
00178
structDBusTypeReader.html
DBusTypeReader
*parent)
00179 {
00180   struct_or_dict_entry_types_only_reader_recurse (sub, parent);
00181
00182
/* struct and dict entry have 8 byte alignment */
00183   sub->
structDBusTypeReader.html#o6
value_pos
= _DBUS_ALIGN_VALUE (sub->
structDBusTypeReader.html#o6
value_pos
, 8);
00184 }
00185
00186
static
void
00187 array_types_only_reader_recurse (
structDBusTypeReader.html
DBusTypeReader
*sub,
00188
structDBusTypeReader.html
DBusTypeReader
*parent)
00189 {
00190   base_reader_recurse (sub, parent);
00191
00192
/* point type_pos at the array element type */
00193   sub->
structDBusTypeReader.html#o4
type_pos
+= 1;
00194
00195
/* Init with values likely to crash things if misused */
00196   sub->
structDBusTypeReader.html#o10
u
.array.start_pos =
group__DBusInternalsUtils.html#ga143
_DBUS_INT_MAX
;
00197   sub->
structDBusTypeReader.html#o2
array_len_offset
= 7;
00198 }
00199
group__DBusMarshal.html#ga183
00202
#define ARRAY_READER_LEN_POS(reader) \
00203
((reader)->u.array.start_pos - ((int)(reader)->array_len_offset) - 4)
00204
00205
static
int
00206 array_reader_get_array_len (
const
structDBusTypeReader.html
DBusTypeReader
*reader)
00207 {
00208
group__DBusTypes.html#ga3
dbus_uint32_t
array_len;
00209
int
len_pos;
00210
00211   len_pos =
group__DBusMarshal.html#ga183
ARRAY_READER_LEN_POS
(reader);
00212
00213
group__DBusInternalsUtils.html#ga130
_dbus_assert
(_DBUS_ALIGN_VALUE (len_pos, 4) == (
unsigned
) len_pos);
00214   array_len = _dbus_unpack_uint32 (reader->
structDBusTypeReader.html#o0
byte_order
,
00215                                    _dbus_string_get_const_data_len (reader->
structDBusTypeReader.html#o5
value_str
, len_pos, 4));
00216
00217
#if RECURSIVE_MARSHAL_READ_TRACE
00218
_dbus_verbose (
"   reader %p len_pos %d array len %u len_offset %d\n"
,
00219                  reader, len_pos, array_len, reader->
structDBusTypeReader.html#o2
array_len_offset
);
00220
#endif
00221
00222
group__DBusInternalsUtils.html#ga130
_dbus_assert
(reader->
structDBusTypeReader.html#o10
u
.array.start_pos - len_pos - 4 < 8);
00223
00224
return
array_len;
00225 }
00226
00227
static
void
00228 array_reader_recurse (
structDBusTypeReader.html
DBusTypeReader
*sub,
00229
structDBusTypeReader.html
DBusTypeReader
*parent)
00230 {
00231
int
alignment;
00232
int
len_pos;
00233
00234   array_types_only_reader_recurse (sub, parent);
00235
00236   sub->
structDBusTypeReader.html#o6
value_pos
= _DBUS_ALIGN_VALUE (sub->
structDBusTypeReader.html#o6
value_pos
, 4);
00237
00238   len_pos = sub->
structDBusTypeReader.html#o6
value_pos
;
00239
00240   sub->
structDBusTypeReader.html#o6
value_pos
+= 4;
/* for the length */
00241
00242   alignment = element_type_get_alignment (sub->
structDBusTypeReader.html#o3
type_str
,
00243                                           sub->
structDBusTypeReader.html#o4
type_pos
);
00244
00245   sub->
structDBusTypeReader.html#o6
value_pos
= _DBUS_ALIGN_VALUE (sub->
structDBusTypeReader.html#o6
value_pos
, alignment);
00246
00247   sub->
structDBusTypeReader.html#o10
u
.array.start_pos = sub->
structDBusTypeReader.html#o6
value_pos
;
00248
group__DBusInternalsUtils.html#ga130
_dbus_assert
((sub->
structDBusTypeReader.html#o10
u
.array.start_pos - (len_pos + 4)) < 8);
/* only 3 bits in array_len_offset */
00249   sub->
structDBusTypeReader.html#o2
array_len_offset
= sub->
structDBusTypeReader.html#o10
u
.array.start_pos - (len_pos + 4);
00250
00251
#if RECURSIVE_MARSHAL_READ_TRACE
00252
_dbus_verbose (
"    type reader %p array start = %d len_offset = %d array len = %d array element type = %s\n"
,
00253                  sub,
00254                  sub->
structDBusTypeReader.html#o10
u
.array.start_pos,
00255                  sub->
structDBusTypeReader.html#o2
array_len_offset
,
00256                  array_reader_get_array_len (sub),
00257
group__DBusMarshal.html#ga42
_dbus_type_to_string
(
group__DBusMarshal.html#ga46
_dbus_first_type_in_signature
(sub->
structDBusTypeReader.html#o3
type_str
,
00258                                                                 sub->
structDBusTypeReader.html#o4
type_pos
)));
00259
#endif
00260
}
00261
00262
static
void
00263 variant_reader_recurse (
structDBusTypeReader.html
DBusTypeReader
*sub,
00264
structDBusTypeReader.html
DBusTypeReader
*parent)
00265 {
00266
int
sig_len;
00267
int
contained_alignment;
00268
00269   base_reader_recurse (sub, parent);
00270
00271
/* Variant is 1 byte sig length (without nul), signature with nul,
00272
* padding to 8-boundary, then values
00273
*/
00274
00275   sig_len = _dbus_string_get_byte (sub->
structDBusTypeReader.html#o5
value_str
, sub->
structDBusTypeReader.html#o6
value_pos
);
00276
00277   sub->
structDBusTypeReader.html#o3
type_str
= sub->
structDBusTypeReader.html#o5
value_str
;
00278   sub->
structDBusTypeReader.html#o4
type_pos
= sub->
structDBusTypeReader.html#o6
value_pos
+ 1;
00279
00280   sub->
structDBusTypeReader.html#o6
value_pos
= sub->
structDBusTypeReader.html#o4
type_pos
+ sig_len + 1;
00281
00282   contained_alignment =
group__DBusMarshal.html#ga40
_dbus_type_get_alignment
(
group__DBusMarshal.html#ga46
_dbus_first_type_in_signature
(sub->
structDBusTypeReader.html#o3
type_str
,
00283                                                                            sub->
structDBusTypeReader.html#o4
type_pos
));
00284
00285   sub->
structDBusTypeReader.html#o6
value_pos
= _DBUS_ALIGN_VALUE (sub->
structDBusTypeReader.html#o6
value_pos
, contained_alignment);
00286
00287
#if RECURSIVE_MARSHAL_READ_TRACE
00288
_dbus_verbose (
"    type reader %p variant containing '%s'\n"
,
00289                  sub,
00290                  _dbus_string_get_const_data_len (sub->
structDBusTypeReader.html#o3
type_str
,
00291                                                   sub->
structDBusTypeReader.html#o4
type_pos
, 0));
00292
#endif
00293
}
00294
00295
static
group__DBusTypes.html#ga2
dbus_bool_t
00296 array_reader_check_finished (
const
structDBusTypeReader.html
DBusTypeReader
*reader)
00297 {
00298
int
end_pos;
00299
00300
/* return the array element type if elements remain, and
00301
* TYPE_INVALID otherwise
00302
*/
00303
00304   end_pos = reader->
structDBusTypeReader.html#o10
u
.array.start_pos + array_reader_get_array_len (reader);
00305
00306
group__DBusInternalsUtils.html#ga130
_dbus_assert
(reader->
structDBusTypeReader.html#o6
value_pos
<= end_pos);
00307
group__DBusInternalsUtils.html#ga130
_dbus_assert
(reader->
structDBusTypeReader.html#o6
value_pos
>= reader->
structDBusTypeReader.html#o10
u
.array.start_pos);
00308
00309
return
reader->
structDBusTypeReader.html#o6
value_pos
== end_pos;
00310 }
00311
00312
static
void
00313 skip_one_complete_type (
const
structDBusString.html
DBusString
*type_str,
00314
int
*type_pos)
00315 {
00316
group__DBusMarshal.html#ga96
_dbus_type_signature_next
(_dbus_string_get_const_data (type_str),
00317                              type_pos);
00318 }
00319
00328
void
group__DBusMarshal.html#ga96
00329
group__DBusMarshal.html#ga96
_dbus_type_signature_next
(
const
char
*type_str,
00330
int
*type_pos)
00331 {
00332
const
unsigned
char
*p;
00333
const
unsigned
char
*start;
00334
00335
group__DBusInternalsUtils.html#ga130
_dbus_assert
(type_str !=
group__DBusMacros.html#ga4
NULL
);
00336
group__DBusInternalsUtils.html#ga130
_dbus_assert
(type_pos !=
group__DBusMacros.html#ga4
NULL
);
00337
00338   start = type_str;
00339   p = start + *type_pos;
00340
00341
group__DBusInternalsUtils.html#ga130
_dbus_assert
(*p != DBUS_STRUCT_END_CHAR);
00342
group__DBusInternalsUtils.html#ga130
_dbus_assert
(*p != DBUS_DICT_ENTRY_END_CHAR);
00343
00344
while
(*p == DBUS_TYPE_ARRAY)
00345     ++p;
00346
00347
group__DBusInternalsUtils.html#ga130
_dbus_assert
(*p != DBUS_STRUCT_END_CHAR);
00348
group__DBusInternalsUtils.html#ga130
_dbus_assert
(*p != DBUS_DICT_ENTRY_END_CHAR);
00349
00350
if
(*p == DBUS_STRUCT_BEGIN_CHAR)
00351     {
00352
int
depth;
00353
00354       depth = 1;
00355
00356
while
(
group__DBusMacros.html#ga2
TRUE
)
00357         {
00358
group__DBusInternalsUtils.html#ga130
_dbus_assert
(*p != DBUS_TYPE_INVALID);
00359
00360           ++p;
00361
00362
group__DBusInternalsUtils.html#ga130
_dbus_assert
(*p != DBUS_TYPE_INVALID);
00363
00364
if
(*p == DBUS_STRUCT_BEGIN_CHAR)
00365             depth += 1;
00366
else
if
(*p == DBUS_STRUCT_END_CHAR)
00367             {
00368               depth -= 1;
00369
if
(depth == 0)
00370                 {
00371                   ++p;
00372
break
;
00373                 }
00374             }
00375         }
00376     }
00377
else
if
(*p == DBUS_DICT_ENTRY_BEGIN_CHAR)
00378     {
00379
int
depth;
00380
00381       depth = 1;
00382
00383
while
(
group__DBusMacros.html#ga2
TRUE
)
00384         {
00385
group__DBusInternalsUtils.html#ga130
_dbus_assert
(*p != DBUS_TYPE_INVALID);
00386
00387           ++p;
00388
00389
group__DBusInternalsUtils.html#ga130
_dbus_assert
(*p != DBUS_TYPE_INVALID);
00390
00391
if
(*p == DBUS_DICT_ENTRY_BEGIN_CHAR)
00392             depth += 1;
00393
else
if
(*p == DBUS_DICT_ENTRY_END_CHAR)
00394             {
00395               depth -= 1;
00396
if
(depth == 0)
00397                 {
00398                   ++p;
00399
break
;
00400                 }
00401             }
00402         }
00403     }
00404
else
00405     {
00406       ++p;
00407     }
00408
00409   *type_pos = (int) (p - start);
00410 }
00411
00412
static
int
00413 find_len_of_complete_type (
const
structDBusString.html
DBusString
*type_str,
00414
int
type_pos)
00415 {
00416
int
end;
00417
00418   end = type_pos;
00419
00420   skip_one_complete_type (type_str, &end);
00421
00422
return
end - type_pos;
00423 }
00424
00425
static
void
00426 base_reader_next (
structDBusTypeReader.html
DBusTypeReader
*reader,
00427
int
current_type)
00428 {
00429
switch
(current_type)
00430     {
00431
case
DBUS_TYPE_DICT_ENTRY:
00432
case
DBUS_TYPE_STRUCT:
00433
case
DBUS_TYPE_VARIANT:
00434
/* Scan forward over the entire container contents */
00435       {
00436
structDBusTypeReader.html
DBusTypeReader
sub;
00437
00438
if
(reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o2
types_only
&& current_type == DBUS_TYPE_VARIANT)
00439           ;
00440
else
00441           {
00442
/* Recurse into the struct or variant */
00443
group__DBusMarshal.html#ga116
_dbus_type_reader_recurse
(reader, &sub);
00444
00445
/* Skip everything in this subreader */
00446
while
(
group__DBusMarshal.html#ga117
_dbus_type_reader_next
(&sub))
00447               {
00448
/* nothing */
;
00449               }
00450           }
00451
if
(!reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o2
types_only
)
00452           reader->
structDBusTypeReader.html#o6
value_pos
= sub.
structDBusTypeReader.html#o6
value_pos
;
00453
00454
/* Now we are at the end of this container; for variants, the
00455
* subreader's type_pos is totally inapplicable (it's in the
00456
* value string) but we know that we increment by one past the
00457
* DBUS_TYPE_VARIANT
00458
*/
00459
if
(current_type == DBUS_TYPE_VARIANT)
00460           reader->
structDBusTypeReader.html#o4
type_pos
+= 1;
00461
else
00462           reader->
structDBusTypeReader.html#o4
type_pos
= sub.
structDBusTypeReader.html#o4
type_pos
;
00463       }
00464
break
;
00465
00466
case
DBUS_TYPE_ARRAY:
00467       {
00468
if
(!reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o2
types_only
)
00469
group__DBusMarshal.html#ga39
_dbus_marshal_skip_array
(reader->
structDBusTypeReader.html#o5
value_str
,
00470
group__DBusMarshal.html#ga46
_dbus_first_type_in_signature
(reader->
structDBusTypeReader.html#o3
type_str
,
00471                                                                    reader->
structDBusTypeReader.html#o4
type_pos
+ 1),
00472                                     reader->
structDBusTypeReader.html#o0
byte_order
,
00473                                     &reader->
structDBusTypeReader.html#o6
value_pos
);
00474
00475         skip_one_complete_type (reader->
structDBusTypeReader.html#o3
type_str
, &reader->
structDBusTypeReader.html#o4
type_pos
);
00476       }
00477
break
;
00478
00479
default
:
00480
if
(!reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o2
types_only
)
00481
group__DBusMarshal.html#ga38
_dbus_marshal_skip_basic
(reader->
structDBusTypeReader.html#o5
value_str
,
00482                                   current_type, reader->
structDBusTypeReader.html#o0
byte_order
,
00483                                   &reader->
structDBusTypeReader.html#o6
value_pos
);
00484
00485       reader->
structDBusTypeReader.html#o4
type_pos
+= 1;
00486
break
;
00487     }
00488 }
00489
00490
static
void
00491 struct_reader_next (
structDBusTypeReader.html
DBusTypeReader
*reader,
00492
int
current_type)
00493 {
00494
int
t;
00495
00496   base_reader_next (reader, current_type);
00497
00498
/* for STRUCT containers we return FALSE at the end of the struct,
00499
* for INVALID we return FALSE at the end of the signature.
00500
* In both cases we arrange for get_current_type() to return INVALID
00501
* which is defined to happen iff we're at the end (no more next())
00502
*/
00503   t = _dbus_string_get_byte (reader->
structDBusTypeReader.html#o3
type_str
, reader->
structDBusTypeReader.html#o4
type_pos
);
00504
if
(t == DBUS_STRUCT_END_CHAR)
00505     {
00506       reader->
structDBusTypeReader.html#o4
type_pos
+= 1;
00507       reader->
structDBusTypeReader.html#o1
finished
=
group__DBusMacros.html#ga2
TRUE
;
00508     }
00509 }
00510
00511
static
void
00512 dict_entry_reader_next (
structDBusTypeReader.html
DBusTypeReader
*reader,
00513
int
current_type)
00514 {
00515
int
t;
00516
00517   base_reader_next (reader, current_type);
00518
00519
/* for STRUCT containers we return FALSE at the end of the struct,
00520
* for INVALID we return FALSE at the end of the signature.
00521
* In both cases we arrange for get_current_type() to return INVALID
00522
* which is defined to happen iff we're at the end (no more next())
00523
*/
00524   t = _dbus_string_get_byte (reader->
structDBusTypeReader.html#o3
type_str
, reader->
structDBusTypeReader.html#o4
type_pos
);
00525
if
(t == DBUS_DICT_ENTRY_END_CHAR)
00526     {
00527       reader->
structDBusTypeReader.html#o4
type_pos
+= 1;
00528       reader->
structDBusTypeReader.html#o1
finished
=
group__DBusMacros.html#ga2
TRUE
;
00529     }
00530 }
00531
00532
static
void
00533 array_types_only_reader_next (
structDBusTypeReader.html
DBusTypeReader
*reader,
00534
int
current_type)
00535 {
00536
/* We have one "element" to be iterated over
00537
* in each array, which is its element type.
00538
* So the finished flag indicates whether we've
00539
* iterated over it yet or not.
00540
*/
00541   reader->
structDBusTypeReader.html#o1
finished
=
group__DBusMacros.html#ga2
TRUE
;
00542 }
00543
00544
static
void
00545 array_reader_next (
structDBusTypeReader.html
DBusTypeReader
*reader,
00546
int
current_type)
00547 {
00548
/* Skip one array element */
00549
int
end_pos;
00550
00551   end_pos = reader->
structDBusTypeReader.html#o10
u
.array.start_pos + array_reader_get_array_len (reader);
00552
00553
#if RECURSIVE_MARSHAL_READ_TRACE
00554
_dbus_verbose (
"  reader %p array next START start_pos = %d end_pos = %d value_pos = %d current_type = %s\n"
,
00555                  reader,
00556                  reader->
structDBusTypeReader.html#o10
u
.array.start_pos,
00557                  end_pos, reader->
structDBusTypeReader.html#o6
value_pos
,
00558
group__DBusMarshal.html#ga42
_dbus_type_to_string
(current_type));
00559
#endif
00560
00561
group__DBusInternalsUtils.html#ga130
_dbus_assert
(reader->
structDBusTypeReader.html#o6
value_pos
< end_pos);
00562
group__DBusInternalsUtils.html#ga130
_dbus_assert
(reader->
structDBusTypeReader.html#o6
value_pos
>= reader->
structDBusTypeReader.html#o10
u
.array.start_pos);
00563
00564
switch
(
group__DBusMarshal.html#ga46
_dbus_first_type_in_signature
(reader->
structDBusTypeReader.html#o3
type_str
,
00565                                    reader->
structDBusTypeReader.html#o4
type_pos
))
00566     {
00567
case
DBUS_TYPE_DICT_ENTRY:
00568
case
DBUS_TYPE_STRUCT:
00569
case
DBUS_TYPE_VARIANT:
00570       {
00571
structDBusTypeReader.html
DBusTypeReader
sub;
00572
00573
/* Recurse into the struct or variant */
00574
group__DBusMarshal.html#ga116
_dbus_type_reader_recurse
(reader, &sub);
00575
00576
/* Skip everything in this element */
00577
while
(
group__DBusMarshal.html#ga117
_dbus_type_reader_next
(&sub))
00578           {
00579
/* nothing */
;
00580           }
00581
00582
/* Now we are at the end of this element */
00583         reader->
structDBusTypeReader.html#o6
value_pos
= sub.value_pos;
00584       }
00585
break
;
00586
00587
case
DBUS_TYPE_ARRAY:
00588       {
00589
group__DBusMarshal.html#ga39
_dbus_marshal_skip_array
(reader->
structDBusTypeReader.html#o5
value_str
,
00590
group__DBusMarshal.html#ga46
_dbus_first_type_in_signature
(reader->
structDBusTypeReader.html#o3
type_str
,
00591                                                            reader->
structDBusTypeReader.html#o4
type_pos
+ 1),
00592                                   reader->
structDBusTypeReader.html#o0
byte_order
,
00593                                   &reader->
structDBusTypeReader.html#o6
value_pos
);
00594       }
00595
break
;
00596
00597
default
:
00598       {
00599
group__DBusMarshal.html#ga38
_dbus_marshal_skip_basic
(reader->
structDBusTypeReader.html#o5
value_str
,
00600                                   current_type, reader->
structDBusTypeReader.html#o0
byte_order
,
00601                                   &reader->
structDBusTypeReader.html#o6
value_pos
);
00602       }
00603
break
;
00604     }
00605
00606
#if RECURSIVE_MARSHAL_READ_TRACE
00607
_dbus_verbose (
"  reader %p array next END start_pos = %d end_pos = %d value_pos = %d current_type = %s\n"
,
00608                  reader,
00609                  reader->
structDBusTypeReader.html#o10
u
.array.start_pos,
00610                  end_pos, reader->
structDBusTypeReader.html#o6
value_pos
,
00611
group__DBusMarshal.html#ga42
_dbus_type_to_string
(current_type));
00612
#endif
00613
00614
group__DBusInternalsUtils.html#ga130
_dbus_assert
(reader->
structDBusTypeReader.html#o6
value_pos
<= end_pos);
00615
00616
if
(reader->
structDBusTypeReader.html#o6
value_pos
== end_pos)
00617     {
00618       skip_one_complete_type (reader->
structDBusTypeReader.html#o3
type_str
,
00619                               &reader->
structDBusTypeReader.html#o4
type_pos
);
00620     }
00621 }
00622
00623
static
void
00624 array_init_from_mark (
structDBusTypeReader.html
DBusTypeReader
*reader,
00625
const
structDBusTypeMark.html
DBusTypeMark
*mark)
00626 {
00627
/* Fill in the array-specific fields from the mark. The general
00628
* fields are already filled in.
00629
*/
00630   reader->
structDBusTypeReader.html#o10
u
.array.start_pos = mark->
structDBusTypeMark.html#o5
array_start_pos
;
00631   reader->
structDBusTypeReader.html#o2
array_len_offset
= mark->
structDBusTypeMark.html#o2
array_len_offset
;
00632 }
00633
00634
static
const
structDBusTypeReaderClass.html
DBusTypeReaderClass
body_reader_class = {
00635
"body"
, 0,
00636
group__DBusMacros.html#ga3
FALSE
,
00637
group__DBusMacros.html#ga4
NULL
,
/* body is always toplevel, so doesn't get recursed into */
00638   NULL,
00639   base_reader_next,
00640   NULL
00641 };
00642
00643
static
const
structDBusTypeReaderClass.html
DBusTypeReaderClass
body_types_only_reader_class = {
00644
"body types"
, 1,
00645
group__DBusMacros.html#ga2
TRUE
,
00646   NULL,
/* body is always toplevel, so doesn't get recursed into */
00647   NULL,
00648   base_reader_next,
00649   NULL
00650 };
00651
00652
static
const
structDBusTypeReaderClass.html
DBusTypeReaderClass
struct_reader_class = {
00653
"struct"
, 2,
00654
group__DBusMacros.html#ga3
FALSE
,
00655   struct_or_dict_entry_reader_recurse,
00656   NULL,
00657   struct_reader_next,
00658   NULL
00659 };
00660
00661
static
const
structDBusTypeReaderClass.html
DBusTypeReaderClass
struct_types_only_reader_class = {
00662
"struct types"
, 3,
00663
group__DBusMacros.html#ga2
TRUE
,
00664   struct_or_dict_entry_types_only_reader_recurse,
00665   NULL,
00666   struct_reader_next,
00667   NULL
00668 };
00669
00670
static
const
structDBusTypeReaderClass.html
DBusTypeReaderClass
dict_entry_reader_class = {
00671
"dict_entry"
, 4,
00672
group__DBusMacros.html#ga3
FALSE
,
00673   struct_or_dict_entry_reader_recurse,
00674   NULL,
00675   dict_entry_reader_next,
00676   NULL
00677 };
00678
00679
static
const
structDBusTypeReaderClass.html
DBusTypeReaderClass
dict_entry_types_only_reader_class = {
00680
"dict_entry types"
, 5,
00681
group__DBusMacros.html#ga2
TRUE
,
00682   struct_or_dict_entry_types_only_reader_recurse,
00683   NULL,
00684   dict_entry_reader_next,
00685   NULL
00686 };
00687
00688
static
const
structDBusTypeReaderClass.html
DBusTypeReaderClass
array_reader_class = {
00689
"array"
, 6,
00690
group__DBusMacros.html#ga3
FALSE
,
00691   array_reader_recurse,
00692   array_reader_check_finished,
00693   array_reader_next,
00694   array_init_from_mark
00695 };
00696
00697
static
const
structDBusTypeReaderClass.html
DBusTypeReaderClass
array_types_only_reader_class = {
00698
"array types"
, 7,
00699
group__DBusMacros.html#ga2
TRUE
,
00700   array_types_only_reader_recurse,
00701   NULL,
00702   array_types_only_reader_next,
00703   NULL
00704 };
00705
00706
static
const
structDBusTypeReaderClass.html
DBusTypeReaderClass
variant_reader_class = {
00707
"variant"
, 8,
00708
group__DBusMacros.html#ga3
FALSE
,
00709   variant_reader_recurse,
00710   NULL,
00711   base_reader_next,
00712   NULL
00713 };
00714
00715
static
const
structDBusTypeReaderClass.html
DBusTypeReaderClass
const
*
00716 all_reader_classes[] = {
00717   &body_reader_class,
00718   &body_types_only_reader_class,
00719   &struct_reader_class,
00720   &struct_types_only_reader_class,
00721   &dict_entry_reader_class,
00722   &dict_entry_types_only_reader_class,
00723   &array_reader_class,
00724   &array_types_only_reader_class,
00725   &variant_reader_class
00726 };
00727
00738
void
group__DBusMarshal.html#ga104
00739
group__DBusMarshal.html#ga104
_dbus_type_reader_init
(
structDBusTypeReader.html
DBusTypeReader
*reader,
00740
int
byte_order,
00741
const
structDBusString.html
DBusString
*type_str,
00742
int
type_pos,
00743
const
structDBusString.html
DBusString
*value_str,
00744
int
value_pos)
00745 {
00746   reader->
structDBusTypeReader.html#o7
klass
= &body_reader_class;
00747
00748   reader_init (reader, byte_order, type_str, type_pos,
00749                value_str, value_pos);
00750
00751
#if RECURSIVE_MARSHAL_READ_TRACE
00752
_dbus_verbose (
"  type reader %p init type_pos = %d value_pos = %d remaining sig '%s'\n"
,
00753                  reader, reader->
structDBusTypeReader.html#o4
type_pos
, reader->
structDBusTypeReader.html#o6
value_pos
,
00754                  _dbus_string_get_const_data_len (reader->
structDBusTypeReader.html#o3
type_str
, reader->
structDBusTypeReader.html#o4
type_pos
, 0));
00755
#endif
00756
}
00757
00769
void
group__DBusMarshal.html#ga105
00770
group__DBusMarshal.html#ga105
_dbus_type_reader_init_from_mark
(
structDBusTypeReader.html
DBusTypeReader
*reader,
00771
int
byte_order,
00772
const
structDBusString.html
DBusString
*type_str,
00773
const
structDBusString.html
DBusString
*value_str,
00774
const
structDBusTypeMark.html
DBusTypeMark
*mark)
00775 {
00776   reader->
structDBusTypeReader.html#o7
klass
= all_reader_classes[mark->
structDBusTypeMark.html#o1
container_type
];
00777
00778   reader_init (reader, byte_order,
00779                mark->
structDBusTypeMark.html#o0
type_pos_in_value_str
? value_str : type_str,
00780                mark->
structDBusTypeMark.html#o3
type_pos
,
00781                value_str, mark->
structDBusTypeMark.html#o4
value_pos
);
00782
00783
if
(reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o6
init_from_mark
)
00784     (* reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o6
init_from_mark
) (reader, mark);
00785
00786
#if RECURSIVE_MARSHAL_READ_TRACE
00787
_dbus_verbose (
"  type reader %p init from mark type_pos = %d value_pos = %d remaining sig '%s'\n"
,
00788                  reader, reader->
structDBusTypeReader.html#o4
type_pos
, reader->
structDBusTypeReader.html#o6
value_pos
,
00789                  _dbus_string_get_const_data_len (reader->
structDBusTypeReader.html#o3
type_str
, reader->
structDBusTypeReader.html#o4
type_pos
, 0));
00790
#endif
00791
}
00792
00801
void
group__DBusMarshal.html#ga106
00802
group__DBusMarshal.html#ga106
_dbus_type_reader_init_types_only
(
structDBusTypeReader.html
DBusTypeReader
*reader,
00803
const
structDBusString.html
DBusString
*type_str,
00804
int
type_pos)
00805 {
00806   reader->
structDBusTypeReader.html#o7
klass
= &body_types_only_reader_class;
00807
00808   reader_init (reader, DBUS_COMPILER_BYTE_ORDER
/* irrelevant */
,
00809                type_str, type_pos, NULL,
group__DBusInternalsUtils.html#ga143
_DBUS_INT_MAX
/* crashes if we screw up */
);
00810
00811
#if RECURSIVE_MARSHAL_READ_TRACE
00812
_dbus_verbose (
"  type reader %p init types only type_pos = %d remaining sig '%s'\n"
,
00813                  reader, reader->
structDBusTypeReader.html#o4
type_pos
,
00814                  _dbus_string_get_const_data_len (reader->
structDBusTypeReader.html#o3
type_str
, reader->
structDBusTypeReader.html#o4
type_pos
, 0));
00815
#endif
00816
}
00817
00826
void
group__DBusMarshal.html#ga107
00827
group__DBusMarshal.html#ga107
_dbus_type_reader_init_types_only_from_mark
(
structDBusTypeReader.html
DBusTypeReader
*reader,
00828
const
structDBusString.html
DBusString
*type_str,
00829
const
structDBusTypeMark.html
DBusTypeMark
*mark)
00830 {
00831   reader->
structDBusTypeReader.html#o7
klass
= all_reader_classes[mark->
structDBusTypeMark.html#o1
container_type
];
00832
group__DBusInternalsUtils.html#ga130
_dbus_assert
(reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o2
types_only
);
00833
group__DBusInternalsUtils.html#ga130
_dbus_assert
(!mark->
structDBusTypeMark.html#o0
type_pos_in_value_str
);
00834
00835   reader_init (reader, DBUS_COMPILER_BYTE_ORDER,
/* irrelevant */
00836                type_str, mark->
structDBusTypeMark.html#o3
type_pos
,
00837                NULL,
group__DBusInternalsUtils.html#ga143
_DBUS_INT_MAX
/* crashes if we screw up */
);
00838
00839
if
(reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o6
init_from_mark
)
00840     (* reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o6
init_from_mark
) (reader, mark);
00841
00842
#if RECURSIVE_MARSHAL_READ_TRACE
00843
_dbus_verbose (
"  type reader %p init types only from mark type_pos = %d remaining sig '%s'\n"
,
00844                  reader, reader->
structDBusTypeReader.html#o4
type_pos
,
00845                  _dbus_string_get_const_data_len (reader->
structDBusTypeReader.html#o3
type_str
, reader->
structDBusTypeReader.html#o4
type_pos
, 0));
00846
#endif
00847
}
00848
00856
void
group__DBusMarshal.html#ga108
00857
group__DBusMarshal.html#ga108
_dbus_type_reader_save_mark
(
const
structDBusTypeReader.html
DBusTypeReader
*reader,
00858
structDBusTypeMark.html
DBusTypeMark
*mark)
00859 {
00860   mark->
structDBusTypeMark.html#o0
type_pos_in_value_str
= (reader->
structDBusTypeReader.html#o3
type_str
== reader->
structDBusTypeReader.html#o5
value_str
);
00861   mark->
structDBusTypeMark.html#o1
container_type
= reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o1
id
;
00862
group__DBusInternalsUtils.html#ga130
_dbus_assert
(all_reader_classes[reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o1
id
] == reader->
structDBusTypeReader.html#o7
klass
);
00863
00864   mark->
structDBusTypeMark.html#o3
type_pos
= reader->
structDBusTypeReader.html#o4
type_pos
;
00865   mark->
structDBusTypeMark.html#o4
value_pos
= reader->
structDBusTypeReader.html#o6
value_pos
;
00866
00867
/* these are just junk if the reader isn't really an array of course */
00868   mark->
structDBusTypeMark.html#o2
array_len_offset
= reader->
structDBusTypeReader.html#o2
array_len_offset
;
00869   mark->
structDBusTypeMark.html#o5
array_start_pos
= reader->
structDBusTypeReader.html#o10
u
.array.start_pos;
00870 }
00871
00880
int
group__DBusMarshal.html#ga109
00881
group__DBusMarshal.html#ga109
_dbus_type_reader_get_current_type
(
const
structDBusTypeReader.html
DBusTypeReader
*reader)
00882 {
00883
int
t;
00884
00885
if
(reader->
structDBusTypeReader.html#o1
finished
||
00886       (reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o4
check_finished
&&
00887        (* reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o4
check_finished
) (reader)))
00888     t = DBUS_TYPE_INVALID;
00889
else
00890     t =
group__DBusMarshal.html#ga46
_dbus_first_type_in_signature
(reader->
structDBusTypeReader.html#o3
type_str
,
00891                                        reader->
structDBusTypeReader.html#o4
type_pos
);
00892
00893
group__DBusInternalsUtils.html#ga130
_dbus_assert
(t != DBUS_STRUCT_END_CHAR);
00894
group__DBusInternalsUtils.html#ga130
_dbus_assert
(t != DBUS_STRUCT_BEGIN_CHAR);
00895
group__DBusInternalsUtils.html#ga130
_dbus_assert
(t != DBUS_DICT_ENTRY_END_CHAR);
00896
group__DBusInternalsUtils.html#ga130
_dbus_assert
(t != DBUS_DICT_ENTRY_BEGIN_CHAR);
00897
00898
#if 0
00899
_dbus_verbose (
"  type reader %p current type_pos = %d type = %s\n"
,
00900                  reader, reader->
structDBusTypeReader.html#o4
type_pos
,
00901
group__DBusMarshal.html#ga42
_dbus_type_to_string
(t));
00902
#endif
00903
00904
return
t;
00905 }
00906
00915
int
group__DBusMarshal.html#ga110
00916
group__DBusMarshal.html#ga110
_dbus_type_reader_get_element_type
(
const
structDBusTypeReader.html
DBusTypeReader
*reader)
00917 {
00918
int
element_type;
00919
00920
group__DBusInternalsUtils.html#ga130
_dbus_assert
(
group__DBusMarshal.html#ga109
_dbus_type_reader_get_current_type
(reader) == DBUS_TYPE_ARRAY);
00921
00922   element_type =
group__DBusMarshal.html#ga46
_dbus_first_type_in_signature
(reader->type_str,
00923                                           reader->type_pos + 1);
00924
00925
return
element_type;
00926 }
00927
00932
int
group__DBusMarshal.html#ga111
00933
group__DBusMarshal.html#ga111
_dbus_type_reader_get_value_pos
(
const
structDBusTypeReader.html
DBusTypeReader
*reader)
00934 {
00935
return
reader->
structDBusTypeReader.html#o6
value_pos
;
00936 }
00937
00947
void
group__DBusMarshal.html#ga112
00948
group__DBusMarshal.html#ga112
_dbus_type_reader_read_raw
(
const
structDBusTypeReader.html
DBusTypeReader
*reader,
00949
const
unsigned
char
**value_location)
00950 {
00951
group__DBusInternalsUtils.html#ga130
_dbus_assert
(!reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o2
types_only
);
00952
00953   *value_location = _dbus_string_get_const_data_len (reader->
structDBusTypeReader.html#o5
value_str
,
00954                                                      reader->
structDBusTypeReader.html#o6
value_pos
,
00955                                                      0);
00956 }
00957
00964
void
group__DBusMarshal.html#ga113
00965
group__DBusMarshal.html#ga113
_dbus_type_reader_read_basic
(
const
structDBusTypeReader.html
DBusTypeReader
*reader,
00966
void
*value)
00967 {
00968
int
t;
00969
00970
group__DBusInternalsUtils.html#ga130
_dbus_assert
(!reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o2
types_only
);
00971
00972   t =
group__DBusMarshal.html#ga109
_dbus_type_reader_get_current_type
(reader);
00973
00974
group__DBusMarshal.html#ga24
_dbus_marshal_read_basic
(reader->
structDBusTypeReader.html#o5
value_str
,
00975                             reader->
structDBusTypeReader.html#o6
value_pos
,
00976                             t, value,
00977                             reader->
structDBusTypeReader.html#o0
byte_order
,
00978                             NULL);
00979
00980
00981
#if RECURSIVE_MARSHAL_READ_TRACE
00982
_dbus_verbose (
"  type reader %p read basic type_pos = %d value_pos = %d remaining sig '%s'\n"
,
00983                  reader, reader->
structDBusTypeReader.html#o4
type_pos
, reader->
structDBusTypeReader.html#o6
value_pos
,
00984                  _dbus_string_get_const_data_len (reader->
structDBusTypeReader.html#o3
type_str
, reader->
structDBusTypeReader.html#o4
type_pos
, 0));
00985
#endif
00986
}
00987
00994
int
group__DBusMarshal.html#ga114
00995
group__DBusMarshal.html#ga114
_dbus_type_reader_get_array_length
(
const
structDBusTypeReader.html
DBusTypeReader
*reader)
00996 {
00997
group__DBusInternalsUtils.html#ga130
_dbus_assert
(!reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o2
types_only
);
00998
group__DBusInternalsUtils.html#ga130
_dbus_assert
(reader->
structDBusTypeReader.html#o7
klass
== &array_reader_class);
00999
01000
return
array_reader_get_array_len (reader);
01001 }
01002
01018
void
group__DBusMarshal.html#ga115
01019
group__DBusMarshal.html#ga115
_dbus_type_reader_read_fixed_multi
(
const
structDBusTypeReader.html
DBusTypeReader
*reader,
01020
void
*value,
01021
int
*n_elements)
01022 {
01023
int
element_type;
01024
int
end_pos;
01025
int
remaining_len;
01026
int
alignment;
01027
int
total_len;
01028
01029
group__DBusInternalsUtils.html#ga130
_dbus_assert
(!reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o2
types_only
);
01030
group__DBusInternalsUtils.html#ga130
_dbus_assert
(reader->
structDBusTypeReader.html#o7
klass
== &array_reader_class);
01031
01032   element_type =
group__DBusMarshal.html#ga46
_dbus_first_type_in_signature
(reader->
structDBusTypeReader.html#o3
type_str
,
01033                                                 reader->
structDBusTypeReader.html#o4
type_pos
);
01034
01035
group__DBusInternalsUtils.html#ga130
_dbus_assert
(element_type != DBUS_TYPE_INVALID);
/* why we don't use get_current_type() */
01036
group__DBusInternalsUtils.html#ga130
_dbus_assert
(
group__DBusSignature.html#ga10
dbus_type_is_fixed
(element_type));
01037
01038   alignment =
group__DBusMarshal.html#ga40
_dbus_type_get_alignment
(element_type);
01039
01040
group__DBusInternalsUtils.html#ga130
_dbus_assert
(reader->
structDBusTypeReader.html#o6
value_pos
>= reader->
structDBusTypeReader.html#o10
u
.array.start_pos);
01041
01042   total_len = array_reader_get_array_len (reader);
01043   end_pos = reader->
structDBusTypeReader.html#o10
u
.array.start_pos + total_len;
01044   remaining_len = end_pos - reader->
structDBusTypeReader.html#o6
value_pos
;
01045
01046
#if RECURSIVE_MARSHAL_READ_TRACE
01047
_dbus_verbose (
"end_pos %d total_len %d remaining_len %d value_pos %d\n"
,
01048                  end_pos, total_len, remaining_len, reader->
structDBusTypeReader.html#o6
value_pos
);
01049
#endif
01050
01051
group__DBusInternalsUtils.html#ga130
_dbus_assert
(remaining_len <= total_len);
01052
01053
if
(remaining_len == 0)
01054     *(
const
unionDBusBasicValue.html
DBusBasicValue
**) value = NULL;
01055
else
01056     *(
const
unionDBusBasicValue.html
DBusBasicValue
**) value =
01057       (
void
*) _dbus_string_get_const_data_len (reader->
structDBusTypeReader.html#o5
value_str
,
01058                                                reader->
structDBusTypeReader.html#o6
value_pos
,
01059                                                remaining_len);
01060
01061   *n_elements = remaining_len / alignment;
01062
group__DBusInternalsUtils.html#ga130
_dbus_assert
((remaining_len % alignment) == 0);
01063
01064
#if RECURSIVE_MARSHAL_READ_TRACE
01065
_dbus_verbose (
"  type reader %p read fixed array type_pos = %d value_pos = %d remaining sig '%s'\n"
,
01066                  reader, reader->
structDBusTypeReader.html#o4
type_pos
, reader->
structDBusTypeReader.html#o6
value_pos
,
01067                  _dbus_string_get_const_data_len (reader->
structDBusTypeReader.html#o3
type_str
, reader->
structDBusTypeReader.html#o4
type_pos
, 0));
01068
#endif
01069
}
01070
01083
void
group__DBusMarshal.html#ga116
01084
group__DBusMarshal.html#ga116
_dbus_type_reader_recurse
(
structDBusTypeReader.html
DBusTypeReader
*reader,
01085
structDBusTypeReader.html
DBusTypeReader
*sub)
01086 {
01087
int
t;
01088
01089   t =
group__DBusMarshal.html#ga46
_dbus_first_type_in_signature
(reader->
structDBusTypeReader.html#o3
type_str
, reader->
structDBusTypeReader.html#o4
type_pos
);
01090
01091
switch
(t)
01092     {
01093
case
DBUS_TYPE_STRUCT:
01094
if
(reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o2
types_only
)
01095         sub->
structDBusTypeReader.html#o7
klass
= &struct_types_only_reader_class;
01096
else
01097         sub->
structDBusTypeReader.html#o7
klass
= &struct_reader_class;
01098
break
;
01099
case
DBUS_TYPE_DICT_ENTRY:
01100
if
(reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o2
types_only
)
01101         sub->
structDBusTypeReader.html#o7
klass
= &dict_entry_types_only_reader_class;
01102
else
01103         sub->
structDBusTypeReader.html#o7
klass
= &dict_entry_reader_class;
01104
break
;
01105
case
DBUS_TYPE_ARRAY:
01106
if
(reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o2
types_only
)
01107         sub->
structDBusTypeReader.html#o7
klass
= &array_types_only_reader_class;
01108
else
01109         sub->
structDBusTypeReader.html#o7
klass
= &array_reader_class;
01110
break
;
01111
case
DBUS_TYPE_VARIANT:
01112
if
(reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o2
types_only
)
01113
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"can't recurse into variant typecode"
);
01114
else
01115         sub->
structDBusTypeReader.html#o7
klass
= &variant_reader_class;
01116
break
;
01117
default
:
01118       _dbus_verbose (
"recursing into type %s\n"
,
group__DBusMarshal.html#ga42
_dbus_type_to_string
(t));
01119
#ifndef DBUS_DISABLE_CHECKS
01120
if
(t == DBUS_TYPE_INVALID)
01121
group__DBusInternalsUtils.html#ga7
_dbus_warn
(
"You can't recurse into an empty array or off the end of a message body\n"
);
01122
#endif
/* DBUS_DISABLE_CHECKS */
01123
01124
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"don't yet handle recursing into this type"
);
01125     }
01126
01127
group__DBusInternalsUtils.html#ga130
_dbus_assert
(sub->
structDBusTypeReader.html#o7
klass
== all_reader_classes[sub->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o1
id
]);
01128
01129   (* sub->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o3
recurse
) (sub, reader);
01130
01131
#if RECURSIVE_MARSHAL_READ_TRACE
01132
_dbus_verbose (
"  type reader %p RECURSED type_pos = %d value_pos = %d remaining sig '%s'\n"
,
01133                  sub, sub->
structDBusTypeReader.html#o4
type_pos
, sub->
structDBusTypeReader.html#o6
value_pos
,
01134                  _dbus_string_get_const_data_len (sub->
structDBusTypeReader.html#o3
type_str
, sub->
structDBusTypeReader.html#o4
type_pos
, 0));
01135
#endif
01136
}
01137
01146
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusMarshal.html#ga117
01147
group__DBusMarshal.html#ga117
_dbus_type_reader_next
(
structDBusTypeReader.html
DBusTypeReader
*reader)
01148 {
01149
int
t;
01150
01151   t =
group__DBusMarshal.html#ga109
_dbus_type_reader_get_current_type
(reader);
01152
01153
#if RECURSIVE_MARSHAL_READ_TRACE
01154
_dbus_verbose (
"  type reader %p START next() { type_pos = %d value_pos = %d remaining sig '%s' current_type = %s\n"
,
01155                  reader, reader->
structDBusTypeReader.html#o4
type_pos
, reader->
structDBusTypeReader.html#o6
value_pos
,
01156                  _dbus_string_get_const_data_len (reader->
structDBusTypeReader.html#o3
type_str
, reader->
structDBusTypeReader.html#o4
type_pos
, 0),
01157
group__DBusMarshal.html#ga42
_dbus_type_to_string
(t));
01158
#endif
01159
01160
if
(t == DBUS_TYPE_INVALID)
01161
return
group__DBusMacros.html#ga3
FALSE
;
01162
01163   (* reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o5
next
) (reader, t);
01164
01165
#if RECURSIVE_MARSHAL_READ_TRACE
01166
_dbus_verbose (
"  type reader %p END next() type_pos = %d value_pos = %d remaining sig '%s' current_type = %s\n"
,
01167                  reader, reader->
structDBusTypeReader.html#o4
type_pos
, reader->
structDBusTypeReader.html#o6
value_pos
,
01168                  _dbus_string_get_const_data_len (reader->
structDBusTypeReader.html#o3
type_str
, reader->
structDBusTypeReader.html#o4
type_pos
, 0),
01169
group__DBusMarshal.html#ga42
_dbus_type_to_string
(
group__DBusMarshal.html#ga109
_dbus_type_reader_get_current_type
(reader)));
01170
#endif
01171
01172
return
group__DBusMarshal.html#ga109
_dbus_type_reader_get_current_type
(reader) != DBUS_TYPE_INVALID;
01173 }
01174
01186
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusMarshal.html#ga118
01187
group__DBusMarshal.html#ga118
_dbus_type_reader_has_next
(
const
structDBusTypeReader.html
DBusTypeReader
*reader)
01188 {
01189
/* Not efficient but works for now. */
01190
structDBusTypeReader.html
DBusTypeReader
copy;
01191
01192   copy = *reader;
01193
return
group__DBusMarshal.html#ga117
_dbus_type_reader_next
(&copy);
01194 }
01195
01217
void
group__DBusMarshal.html#ga119
01218
group__DBusMarshal.html#ga119
_dbus_type_reader_get_signature
(
const
structDBusTypeReader.html
DBusTypeReader
*reader,
01219
const
structDBusString.html
DBusString
**str_p,
01220
int
*start_p,
01221
int
*len_p)
01222 {
01223   *str_p = reader->
structDBusTypeReader.html#o3
type_str
;
01224   *start_p = reader->
structDBusTypeReader.html#o4
type_pos
;
01225   *len_p = find_len_of_complete_type (reader->
structDBusTypeReader.html#o3
type_str
, reader->
structDBusTypeReader.html#o4
type_pos
);
01226 }
01227
structReplacementBlock.html
01228
typedef
struct
01229
{
structReplacementBlock.html#o0
01230
structDBusString.html
DBusString
replacement;
structReplacementBlock.html#o1
01231
int
padding;
01232 }
structReplacementBlock.html
ReplacementBlock
;
01233
01234
static
group__DBusTypes.html#ga2
dbus_bool_t
01235 replacement_block_init (
structReplacementBlock.html
ReplacementBlock
*block,
01236
structDBusTypeReader.html
DBusTypeReader
*reader)
01237 {
01238
if
(!
group__DBusString.html#ga6
_dbus_string_init
(&block->
structReplacementBlock.html#o0
replacement
))
01239
return
group__DBusMacros.html#ga3
FALSE
;
01240
01241
/* % 8 is the padding to have the same align properties in
01242
* our replacement string as we do at the position being replaced
01243
*/
01244   block->
structReplacementBlock.html#o1
padding
= reader->
structDBusTypeReader.html#o6
value_pos
% 8;
01245
01246
if
(!
group__DBusString.html#ga19
_dbus_string_lengthen
(&block->
structReplacementBlock.html#o0
replacement
, block->
structReplacementBlock.html#o1
padding
))
01247
goto
oom;
01248
01249
return
group__DBusMacros.html#ga2
TRUE
;
01250
01251  oom:
01252
group__DBusString.html#ga9
_dbus_string_free
(&block->
structReplacementBlock.html#o0
replacement
);
01253
return
group__DBusMacros.html#ga3
FALSE
;
01254 }
01255
01256
static
group__DBusTypes.html#ga2
dbus_bool_t
01257 replacement_block_replace (
structReplacementBlock.html
ReplacementBlock
*block,
01258
structDBusTypeReader.html
DBusTypeReader
*reader,
01259
const
structDBusTypeReader.html
DBusTypeReader
*realign_root)
01260 {
01261
structDBusTypeWriter.html
DBusTypeWriter
writer;
01262
structDBusTypeReader.html
DBusTypeReader
realign_reader;
01263
structDBusList.html
DBusList
*fixups;
01264
int
orig_len;
01265
01266
group__DBusInternalsUtils.html#ga130
_dbus_assert
(realign_root != NULL);
01267
01268   orig_len = _dbus_string_get_length (&block->
structReplacementBlock.html#o0
replacement
);
01269
01270   realign_reader = *realign_root;
01271
01272
#if RECURSIVE_MARSHAL_WRITE_TRACE
01273
_dbus_verbose (
"INITIALIZING replacement block writer %p at value_pos %d\n"
,
01274                  &writer, _dbus_string_get_length (&block->
structReplacementBlock.html#o0
replacement
));
01275
#endif
01276
group__DBusMarshal.html#ga132
_dbus_type_writer_init_values_only
(&writer,
01277                                       realign_reader.
structDBusTypeReader.html#o0
byte_order
,
01278                                       realign_reader.
structDBusTypeReader.html#o3
type_str
,
01279                                       realign_reader.
structDBusTypeReader.html#o4
type_pos
,
01280                                       &block->
structReplacementBlock.html#o0
replacement
,
01281                                       _dbus_string_get_length (&block->
structReplacementBlock.html#o0
replacement
));
01282
01283
group__DBusInternalsUtils.html#ga130
_dbus_assert
(realign_reader.
structDBusTypeReader.html#o6
value_pos
<= reader->
structDBusTypeReader.html#o6
value_pos
);
01284
01285
#if RECURSIVE_MARSHAL_WRITE_TRACE
01286
_dbus_verbose (
"COPYING from reader at value_pos %d to writer %p starting after value_pos %d\n"
,
01287                  realign_reader.
structDBusTypeReader.html#o6
value_pos
, &writer, reader->
structDBusTypeReader.html#o6
value_pos
);
01288
#endif
01289
fixups = NULL;
01290
if
(!
group__DBusMarshal.html#ga149
_dbus_type_writer_write_reader_partial
(&writer,
01291                                                &realign_reader,
01292                                                reader,
01293                                                block->
structReplacementBlock.html#o1
padding
,
01294                                                _dbus_string_get_length (&block->
structReplacementBlock.html#o0
replacement
) - block->
structReplacementBlock.html#o1
padding
,
01295                                                &fixups))
01296
goto
oom;
01297
01298
#if RECURSIVE_MARSHAL_WRITE_TRACE
01299
_dbus_verbose (
"REPLACEMENT at padding %d len %d\n"
, block->
structReplacementBlock.html#o1
padding
,
01300                  _dbus_string_get_length (&block->
structReplacementBlock.html#o0
replacement
) - block->
structReplacementBlock.html#o1
padding
);
01301
group__DBusMarshal.html#ga44
_dbus_verbose_bytes_of_string
(&block->
structReplacementBlock.html#o0
replacement
, block->
structReplacementBlock.html#o1
padding
,
01302                                  _dbus_string_get_length (&block->
structReplacementBlock.html#o0
replacement
) - block->
structReplacementBlock.html#o1
padding
);
01303   _dbus_verbose (
"TO BE REPLACED at value_pos = %d (align pad %d) len %d realign_reader.value_pos %d\n"
,
01304                  reader->
structDBusTypeReader.html#o6
value_pos
, reader->
structDBusTypeReader.html#o6
value_pos
% 8,
01305                  realign_reader.
structDBusTypeReader.html#o6
value_pos
- reader->
structDBusTypeReader.html#o6
value_pos
,
01306                  realign_reader.
structDBusTypeReader.html#o6
value_pos
);
01307
group__DBusMarshal.html#ga44
_dbus_verbose_bytes_of_string
(reader->
structDBusTypeReader.html#o5
value_str
,
01308                                  reader->
structDBusTypeReader.html#o6
value_pos
,
01309                                  realign_reader.
structDBusTypeReader.html#o6
value_pos
- reader->
structDBusTypeReader.html#o6
value_pos
);
01310
#endif
01311
01312
/* Move the replacement into position
01313
* (realign_reader should now be at the end of the block to be replaced)
01314
*/
01315
if
(!
group__DBusString.html#ga43
_dbus_string_replace_len
(&block->
structReplacementBlock.html#o0
replacement
, block->
structReplacementBlock.html#o1
padding
,
01316                                  _dbus_string_get_length (&block->
structReplacementBlock.html#o0
replacement
) - block->
structReplacementBlock.html#o1
padding
,
01317                                  (
structDBusString.html
DBusString
*) reader->
structDBusTypeReader.html#o5
value_str
,
01318                                  reader->
structDBusTypeReader.html#o6
value_pos
,
01319                                  realign_reader.
structDBusTypeReader.html#o6
value_pos
- reader->
structDBusTypeReader.html#o6
value_pos
))
01320
goto
oom;
01321
01322
/* Process our fixups now that we can't have an OOM error */
01323   apply_and_free_fixups (&fixups, reader);
01324
01325
return
group__DBusMacros.html#ga2
TRUE
;
01326
01327  oom:
01328
group__DBusString.html#ga21
_dbus_string_set_length
(&block->
structReplacementBlock.html#o0
replacement
, orig_len);
01329   free_fixups (&fixups);
01330
return
group__DBusMacros.html#ga3
FALSE
;
01331 }
01332
01333
static
void
01334 replacement_block_free (
structReplacementBlock.html
ReplacementBlock
*block)
01335 {
01336
group__DBusString.html#ga9
_dbus_string_free
(&block->
structReplacementBlock.html#o0
replacement
);
01337 }
01338
01339
/* In the variable-length case, we have to fix alignment after we insert.
01340
* The strategy is as follows:
01341
*
01342
*  - pad a new string to have the same alignment as the
01343
*    start of the current basic value
01344
*  - write the new basic value
01345
*  - copy from the original reader to the new string,
01346
*    which will fix the alignment of types following
01347
*    the new value
01348
*    - this copy has to start at realign_root,
01349
*      but not really write anything until it
01350
*      passes the value being set
01351
*    - as an optimization, we can stop copying
01352
*      when the source and dest values are both
01353
*      on an 8-boundary, since we know all following
01354
*      padding and alignment will be identical
01355
*  - copy the new string back to the original
01356
*    string, replacing the relevant part of the
01357
*    original string
01358
*  - now any arrays in the original string that
01359
*    contained the replaced string may have the
01360
*    wrong length; so we have to fix that
01361
*/
01362
static
group__DBusTypes.html#ga2
dbus_bool_t
01363 reader_set_basic_variable_length (
structDBusTypeReader.html
DBusTypeReader
*reader,
01364
int
current_type,
01365
const
void
*value,
01366
const
structDBusTypeReader.html
DBusTypeReader
*realign_root)
01367 {
01368
group__DBusTypes.html#ga2
dbus_bool_t
retval;
01369
structReplacementBlock.html
ReplacementBlock
block;
01370
structDBusTypeWriter.html
DBusTypeWriter
writer;
01371
01372
group__DBusInternalsUtils.html#ga130
_dbus_assert
(realign_root != NULL);
01373
01374   retval =
group__DBusMacros.html#ga3
FALSE
;
01375
01376
if
(!replacement_block_init (&block, reader))
01377
return
group__DBusMacros.html#ga3
FALSE
;
01378
01379
/* Write the new basic value */
01380
#if RECURSIVE_MARSHAL_WRITE_TRACE
01381
_dbus_verbose (
"INITIALIZING writer %p to write basic value at value_pos %d of replacement string\n"
,
01382                  &writer, _dbus_string_get_length (&block.replacement));
01383
#endif
01384
group__DBusMarshal.html#ga132
_dbus_type_writer_init_values_only
(&writer,
01385                                       reader->
structDBusTypeReader.html#o0
byte_order
,
01386                                       reader->
structDBusTypeReader.html#o3
type_str
,
01387                                       reader->
structDBusTypeReader.html#o4
type_pos
,
01388                                       &block.replacement,
01389                                       _dbus_string_get_length (&block.replacement));
01390
#if RECURSIVE_MARSHAL_WRITE_TRACE
01391
_dbus_verbose (
"WRITING basic value to writer %p (replacement string)\n"
, &writer);
01392
#endif
01393
if
(!
group__DBusMarshal.html#ga144
_dbus_type_writer_write_basic
(&writer, current_type, value))
01394
goto
out;
01395
01396
if
(!replacement_block_replace (&block,
01397                                   reader,
01398                                   realign_root))
01399
goto
out;
01400
01401   retval =
group__DBusMacros.html#ga2
TRUE
;
01402
01403  out:
01404   replacement_block_free (&block);
01405
return
retval;
01406 }
01407
01408
static
void
01409 reader_set_basic_fixed_length (
structDBusTypeReader.html
DBusTypeReader
*reader,
01410
int
current_type,
01411
const
void
*value)
01412 {
01413
group__DBusMarshal.html#ga22
_dbus_marshal_set_basic
((
structDBusString.html
DBusString
*) reader->
structDBusTypeReader.html#o5
value_str
,
01414                            reader->
structDBusTypeReader.html#o6
value_pos
,
01415                            current_type,
01416                            value,
01417                            reader->
structDBusTypeReader.html#o0
byte_order
,
01418                            NULL, NULL);
01419 }
01420
01455
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusMarshal.html#ga125
01456
group__DBusMarshal.html#ga125
_dbus_type_reader_set_basic
(
structDBusTypeReader.html
DBusTypeReader
*reader,
01457
const
void
*value,
01458
const
structDBusTypeReader.html
DBusTypeReader
*realign_root)
01459 {
01460
int
current_type;
01461
01462
group__DBusInternalsUtils.html#ga130
_dbus_assert
(!reader->
structDBusTypeReader.html#o7
klass
->
structDBusTypeReaderClass.html#o2
types_only
);
01463
group__DBusInternalsUtils.html#ga130
_dbus_assert
(reader->
structDBusTypeReader.html#o5
value_str
== realign_root->
structDBusTypeReader.html#o5
value_str
);
01464
group__DBusInternalsUtils.html#ga130
_dbus_assert
(reader->
structDBusTypeReader.html#o6
value_pos
>= realign_root->
structDBusTypeReader.html#o6
value_pos
);
01465
01466   current_type =
group__DBusMarshal.html#ga109
_dbus_type_reader_get_current_type
(reader);
01467
01468
#if RECURSIVE_MARSHAL_WRITE_TRACE
01469
_dbus_verbose (
"  SET BASIC type reader %p type_pos = %d value_pos = %d remaining sig '%s' realign_root = %p with value_pos %d current_type = %s\n"
,
01470                  reader, reader->
structDBusTypeReader.html#o4
type_pos
, reader->
structDBusTypeReader.html#o6
value_pos
,
01471                  _dbus_string_get_const_data_len (reader->
structDBusTypeReader.html#o3
type_str
, reader->
structDBusTypeReader.html#o4
type_pos
, 0),
01472                  realign_root,
01473                  realign_root ? realign_root->
structDBusTypeReader.html#o6
value_pos
: -1,
01474
group__DBusMarshal.html#ga42
_dbus_type_to_string
(current_type));
01475
group__DBusMarshal.html#ga44
_dbus_verbose_bytes_of_string
(realign_root->
structDBusTypeReader.html#o5
value_str
, realign_root->
structDBusTypeReader.html#o6
value_pos
,
01476                                  _dbus_string_get_length (realign_root->
structDBusTypeReader.html#o5
value_str
) -
01477                                  realign_root->
structDBusTypeReader.html#o6
value_pos
);
01478
#endif
01479
01480
group__DBusInternalsUtils.html#ga130
_dbus_assert
(
group__DBusSignature.html#ga9
dbus_type_is_basic
(current_type));
01481
01482
if
(
group__DBusSignature.html#ga10
dbus_type_is_fixed
(current_type))
01483     {
01484       reader_set_basic_fixed_length (reader, current_type, value);
01485
return
group__DBusMacros.html#ga2
TRUE
;
01486     }
01487
else
01488     {
01489
group__DBusInternalsUtils.html#ga130
_dbus_assert
(realign_root != NULL);
01490
return
reader_set_basic_variable_length (reader, current_type,
01491                                                value, realign_root);
01492     }
01493 }
01494
01512
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusMarshal.html#ga126
01513
group__DBusMarshal.html#ga126
_dbus_type_reader_delete
(
structDBusTypeReader.html
DBusTypeReader
*reader,
01514
const
structDBusTypeReader.html
DBusTypeReader
*realign_root)
01515 {
01516
group__DBusTypes.html#ga2
dbus_bool_t
retval;
01517
structReplacementBlock.html
ReplacementBlock
block;
01518
01519
group__DBusInternalsUtils.html#ga130
_dbus_assert
(realign_root != NULL);
01520
group__DBusInternalsUtils.html#ga130
_dbus_assert
(reader->
structDBusTypeReader.html#o7
klass
== &array_reader_class);
01521
01522   retval =
group__DBusMacros.html#ga3
FALSE
;
01523
01524
if
(!replacement_block_init (&block, reader))
01525
return
group__DBusMacros.html#ga3
FALSE
;
01526
01527
if
(!replacement_block_replace (&block,
01528                                   reader,
01529                                   realign_root))
01530
goto
out;
01531
01532   retval =
group__DBusMacros.html#ga2
TRUE
;
01533
01534  out:
01535   replacement_block_free (&block);
01536
return
retval;
01537 }
01538
01547
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusMarshal.html#ga127
01548
group__DBusMarshal.html#ga127
_dbus_type_reader_greater_than
(
const
structDBusTypeReader.html
DBusTypeReader
*lhs,
01549
const
structDBusTypeReader.html
DBusTypeReader
*rhs)
01550 {
01551
group__DBusInternalsUtils.html#ga130
_dbus_assert
(lhs->
structDBusTypeReader.html#o5
value_str
== rhs->
structDBusTypeReader.html#o5
value_str
);
01552
01553
return
lhs->
structDBusTypeReader.html#o6
value_pos
> rhs->
structDBusTypeReader.html#o6
value_pos
;
01554 }
01555
01556
/*
01557
*
01558
*
01559
*         DBusTypeWriter
01560
*
01561
*
01562
*
01563
*/
01564
01585
void
group__DBusMarshal.html#ga128
01586
group__DBusMarshal.html#ga128
_dbus_type_writer_init
(
structDBusTypeWriter.html
DBusTypeWriter
*writer,
01587
int
byte_order,
01588
structDBusString.html
DBusString
*type_str,
01589
int
type_pos,
01590
structDBusString.html
DBusString
*value_str,
01591
int
value_pos)
01592 {
01593   writer->
structDBusTypeWriter.html#o0
byte_order
= byte_order;
01594   writer->
structDBusTypeWriter.html#o4
type_str
= type_str;
01595   writer->
structDBusTypeWriter.html#o5
type_pos
= type_pos;
01596   writer->
structDBusTypeWriter.html#o6
value_str
= value_str;
01597   writer->
structDBusTypeWriter.html#o7
value_pos
= value_pos;
01598   writer->
structDBusTypeWriter.html#o1
container_type
= DBUS_TYPE_INVALID;
01599   writer->
structDBusTypeWriter.html#o2
type_pos_is_expectation
=
group__DBusMacros.html#ga3
FALSE
;
01600   writer->
structDBusTypeWriter.html#o3
enabled
=
group__DBusMacros.html#ga2
TRUE
;
01601
01602
#if RECURSIVE_MARSHAL_WRITE_TRACE
01603
_dbus_verbose (
"writer %p init remaining sig '%s'\n"
, writer,
01604                  writer->
structDBusTypeWriter.html#o4
type_str
?
01605                  _dbus_string_get_const_data_len (writer->
structDBusTypeWriter.html#o4
type_str
, writer->
structDBusTypeWriter.html#o5
type_pos
, 0) :
01606
"unknown"
);
01607
#endif
01608
}
01609
01620
void
group__DBusMarshal.html#ga129
01621
group__DBusMarshal.html#ga129
_dbus_type_writer_init_types_delayed
(
structDBusTypeWriter.html
DBusTypeWriter
*writer,
01622
int
byte_order,
01623
structDBusString.html
DBusString
*value_str,
01624
int
value_pos)
01625 {
01626
group__DBusMarshal.html#ga128
_dbus_type_writer_init
(writer, byte_order,
01627                           NULL, 0, value_str, value_pos);
01628 }
01629
01638
void
group__DBusMarshal.html#ga130
01639
group__DBusMarshal.html#ga130
_dbus_type_writer_add_types
(
structDBusTypeWriter.html
DBusTypeWriter
*writer,
01640
structDBusString.html
DBusString
*type_str,
01641
int
type_pos)
01642 {
01643
if
(writer->
structDBusTypeWriter.html#o4
type_str
== NULL)
/* keeps us from using this as setter */
01644     {
01645       writer->
structDBusTypeWriter.html#o4
type_str
= type_str;
01646       writer->
structDBusTypeWriter.html#o5
type_pos
= type_pos;
01647     }
01648 }
01649
01655
void
group__DBusMarshal.html#ga131
01656
group__DBusMarshal.html#ga131
_dbus_type_writer_remove_types
(
structDBusTypeWriter.html
DBusTypeWriter
*writer)
01657 {
01658   writer->
structDBusTypeWriter.html#o4
type_str
= NULL;
01659   writer->
structDBusTypeWriter.html#o5
type_pos
= -1;
01660 }
01661
01676
void
group__DBusMarshal.html#ga132
01677
group__DBusMarshal.html#ga132
_dbus_type_writer_init_values_only
(
structDBusTypeWriter.html
DBusTypeWriter
*writer,
01678
int
byte_order,
01679
const
structDBusString.html
DBusString
*type_str,
01680
int
type_pos,
01681
structDBusString.html
DBusString
*value_str,
01682
int
value_pos)
01683 {
01684
group__DBusMarshal.html#ga128
_dbus_type_writer_init
(writer, byte_order,
01685                           (
structDBusString.html
DBusString
*)type_str, type_pos,
01686                           value_str, value_pos);
01687
01688   writer->
structDBusTypeWriter.html#o2
type_pos_is_expectation
=
group__DBusMacros.html#ga2
TRUE
;
01689 }
01690
01691
static
group__DBusTypes.html#ga2
dbus_bool_t
01692 _dbus_type_writer_write_basic_no_typecode (
structDBusTypeWriter.html
DBusTypeWriter
*writer,
01693
int
type,
01694
const
void
*value)
01695 {
01696
if
(writer->
structDBusTypeWriter.html#o3
enabled
)
01697
return
group__DBusMarshal.html#ga32
_dbus_marshal_write_basic
(writer->
structDBusTypeWriter.html#o6
value_str
,
01698                                       writer->
structDBusTypeWriter.html#o7
value_pos
,
01699                                       type,
01700                                       value,
01701                                       writer->
structDBusTypeWriter.html#o0
byte_order
,
01702                                       &writer->
structDBusTypeWriter.html#o7
value_pos
);
01703
else
01704
return
group__DBusMacros.html#ga2
TRUE
;
01705 }
01706
01707
/* If our parent is an array, things are a little bit complicated.
01708
*
01709
* The parent must have a complete element type, such as
01710
* "i" or "aai" or "(ii)" or "a(ii)". There can't be
01711
* unclosed parens, or an "a" with no following type.
01712
*
01713
* To recurse, the only allowed operation is to recurse into the
01714
* first type in the element type. So for "i" you can't recurse, for
01715
* "ai" you can recurse into the array, for "(ii)" you can recurse
01716
* into the struct.
01717
*
01718
* If you recurse into the array for "ai", then you must specify
01719
* "i" for the element type of the array you recurse into.
01720
*
01721
* While inside an array at any level, we need to avoid writing to
01722
* type_str, since the type only appears once for the whole array,
01723
* it does not appear for each array element.
01724
*
01725
* While inside an array type_pos points to the expected next
01726
* typecode, rather than the next place we could write a typecode.
01727
*/
01728
static
void
01729 writer_recurse_init_and_check (
structDBusTypeWriter.html
DBusTypeWriter
*writer,
01730
int
container_type,
01731
structDBusTypeWriter.html
DBusTypeWriter
*sub)
01732 {
01733
group__DBusMarshal.html#ga128
_dbus_type_writer_init
(sub,
01734                           writer->
structDBusTypeWriter.html#o0
byte_order
,
01735                           writer->
structDBusTypeWriter.html#o4
type_str
,
01736                           writer->
structDBusTypeWriter.html#o5
type_pos
,
01737                           writer->
structDBusTypeWriter.html#o6
value_str
,
01738                           writer->
structDBusTypeWriter.html#o7
value_pos
);
01739
01740   sub->
structDBusTypeWriter.html#o1
container_type
= container_type;
01741
01742
if
(writer->
structDBusTypeWriter.html#o2
type_pos_is_expectation
||
01743       (sub->
structDBusTypeWriter.html#o1
container_type
== DBUS_TYPE_ARRAY || sub->
structDBusTypeWriter.html#o1
container_type
== DBUS_TYPE_VARIANT))
01744     sub->
structDBusTypeWriter.html#o2
type_pos_is_expectation
=
group__DBusMacros.html#ga2
TRUE
;
01745
else
01746     sub->
structDBusTypeWriter.html#o2
type_pos_is_expectation
=
group__DBusMacros.html#ga3
FALSE
;
01747
01748   sub->
structDBusTypeWriter.html#o3
enabled
= writer->
structDBusTypeWriter.html#o3
enabled
;
01749
01750
#ifndef DBUS_DISABLE_CHECKS
01751
if
(writer->
structDBusTypeWriter.html#o2
type_pos_is_expectation
&& writer->
structDBusTypeWriter.html#o4
type_str
)
01752     {
01753
int
expected;
01754
01755       expected =
group__DBusMarshal.html#ga46
_dbus_first_type_in_signature
(writer->
structDBusTypeWriter.html#o4
type_str
, writer->
structDBusTypeWriter.html#o5
type_pos
);
01756
01757
if
(expected != sub->
structDBusTypeWriter.html#o1
container_type
)
01758         {
01759
group__DBusInternalsUtils.html#ga7
_dbus_warn
(
"Writing an element of type %s, but the expected type here is %s\n"
,
01760
group__DBusMarshal.html#ga42
_dbus_type_to_string
(sub->
structDBusTypeWriter.html#o1
container_type
),
01761
group__DBusMarshal.html#ga42
_dbus_type_to_string
(expected));
01762
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"bad array element or variant content written"
);
01763         }
01764     }
01765
#endif
/* DBUS_DISABLE_CHECKS */
01766
01767
#if RECURSIVE_MARSHAL_WRITE_TRACE
01768
_dbus_verbose (
"  type writer %p recurse parent %s type_pos = %d value_pos = %d is_expectation = %d remaining sig '%s' enabled = %d\n"
,
01769                  writer,
01770
group__DBusMarshal.html#ga42
_dbus_type_to_string
(writer->
structDBusTypeWriter.html#o1
container_type
),
01771                  writer->
structDBusTypeWriter.html#o5
type_pos
, writer->
structDBusTypeWriter.html#o7
value_pos
, writer->
structDBusTypeWriter.html#o2
type_pos_is_expectation
,
01772                  writer->
structDBusTypeWriter.html#o4
type_str
?
01773                  _dbus_string_get_const_data_len (writer->
structDBusTypeWriter.html#o4
type_str
, writer->
structDBusTypeWriter.html#o5
type_pos
, 0) :
01774
"unknown"
,
01775                  writer->
structDBusTypeWriter.html#o3
enabled
);
01776   _dbus_verbose (
"  type writer %p recurse sub %s   type_pos = %d value_pos = %d is_expectation = %d enabled = %d\n"
,
01777                  sub,
01778
group__DBusMarshal.html#ga42
_dbus_type_to_string
(sub->
structDBusTypeWriter.html#o1
container_type
),
01779                  sub->
structDBusTypeWriter.html#o5
type_pos
, sub->
structDBusTypeWriter.html#o7
value_pos
,
01780                  sub->
structDBusTypeWriter.html#o2
type_pos_is_expectation
,
01781                  sub->
structDBusTypeWriter.html#o3
enabled
);
01782
#endif
01783
}
01784
01785
static
group__DBusTypes.html#ga2
dbus_bool_t
01786 write_or_verify_typecode (
structDBusTypeWriter.html
DBusTypeWriter
*writer,
01787
int
typecode)
01788 {
01789
/* A subwriter inside an array or variant will have type_pos
01790
* pointing to the expected typecode; a writer not inside an array
01791
* or variant has type_pos pointing to the next place to insert a
01792
* typecode.
01793
*/
01794
#if RECURSIVE_MARSHAL_WRITE_TRACE
01795
_dbus_verbose (
"  type writer %p write_or_verify start type_pos = %d remaining sig '%s' enabled = %d\n"
,
01796                  writer, writer->
structDBusTypeWriter.html#o5
type_pos
,
01797                  writer->
structDBusTypeWriter.html#o4
type_str
?
01798                  _dbus_string_get_const_data_len (writer->
structDBusTypeWriter.html#o4
type_str
, writer->
structDBusTypeWriter.html#o5
type_pos
, 0) :
01799
"unknown"
,
01800                  writer->
structDBusTypeWriter.html#o3
enabled
);
01801
#endif
01802
01803
if
(writer->
structDBusTypeWriter.html#o4
type_str
== NULL)
01804
return
group__DBusMacros.html#ga2
TRUE
;
01805
01806
if
(writer->
structDBusTypeWriter.html#o2
type_pos_is_expectation
)
01807     {
01808
#ifndef DBUS_DISABLE_CHECKS
01809
{
01810
int
expected;
01811
01812         expected = _dbus_string_get_byte (writer->
structDBusTypeWriter.html#o4
type_str
, writer->
structDBusTypeWriter.html#o5
type_pos
);
01813
01814
if
(expected != typecode)
01815           {
01816
group__DBusInternalsUtils.html#ga7
_dbus_warn
(
"Array or variant type requires that type %s be written, but %s was written\n"
,
01817
group__DBusMarshal.html#ga42
_dbus_type_to_string
(expected),
group__DBusMarshal.html#ga42
_dbus_type_to_string
(typecode));
01818
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"bad type inserted somewhere inside an array or variant"
);
01819           }
01820       }
01821
#endif
/* DBUS_DISABLE_CHECKS */
01822
01823
/* if immediately inside an array we'd always be appending an element,
01824
* so the expected type doesn't change; if inside a struct or something
01825
* below an array, we need to move through said struct or something.
01826
*/
01827
if
(writer->
structDBusTypeWriter.html#o1
container_type
!= DBUS_TYPE_ARRAY)
01828         writer->
structDBusTypeWriter.html#o5
type_pos
+= 1;
01829     }
01830
else
01831     {
01832
if
(!
group__DBusString.html#ga15
_dbus_string_insert_byte
(writer->
structDBusTypeWriter.html#o4
type_str
,
01833                                      writer->
structDBusTypeWriter.html#o5
type_pos
,
01834                                      typecode))
01835
return
group__DBusMacros.html#ga3
FALSE
;
01836
01837       writer->
structDBusTypeWriter.html#o5
type_pos
+= 1;
01838     }
01839
01840
#if RECURSIVE_MARSHAL_WRITE_TRACE
01841
_dbus_verbose (
"  type writer %p write_or_verify end type_pos = %d remaining sig '%s'\n"
,
01842                  writer, writer->
structDBusTypeWriter.html#o5
type_pos
,
01843                  _dbus_string_get_const_data_len (writer->
structDBusTypeWriter.html#o4
type_str
, writer->
structDBusTypeWriter.html#o5
type_pos
, 0));
01844
#endif
01845
01846
return
group__DBusMacros.html#ga2
TRUE
;
01847 }
01848
01849
static
group__DBusTypes.html#ga2
dbus_bool_t
01850 writer_recurse_struct_or_dict_entry (
structDBusTypeWriter.html
DBusTypeWriter
*writer,
01851
int
begin_char,
01852
const
structDBusString.html
DBusString
*contained_type,
01853
int
contained_type_start,
01854
int
contained_type_len,
01855
structDBusTypeWriter.html
DBusTypeWriter
*sub)
01856 {
01857
/* FIXME right now contained_type is ignored; we could probably
01858
* almost trivially fix the code so if it's present we
01859
* write it out and then set type_pos_is_expectation
01860
*/
01861
01862
/* Ensure that we'll be able to add alignment padding and the typecode */
01863
if
(writer->
structDBusTypeWriter.html#o3
enabled
)
01864     {
01865
if
(!
group__DBusString.html#ga25
_dbus_string_alloc_space
(sub->
structDBusTypeWriter.html#o6
value_str
, 8))
01866
return
group__DBusMacros.html#ga3
FALSE
;
01867     }
01868
01869
if
(!write_or_verify_typecode (sub, begin_char))
01870
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"failed to insert struct typecode after prealloc"
);
01871
01872
if
(writer->
structDBusTypeWriter.html#o3
enabled
)
01873     {
01874
if
(!
group__DBusString.html#ga14
_dbus_string_insert_bytes
(sub->value_str,
01875                                       sub->value_pos,
01876                                       _DBUS_ALIGN_VALUE (sub->value_pos, 8) - sub->value_pos,
01877
'\0'
))
01878
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"should not have failed to insert alignment padding for struct"
);
01879       sub->value_pos = _DBUS_ALIGN_VALUE (sub->value_pos, 8);
01880     }
01881
01882
return
group__DBusMacros.html#ga2
TRUE
;
01883 }
01884
01885
01886
static
group__DBusTypes.html#ga2
dbus_bool_t
01887 writer_recurse_array (
structDBusTypeWriter.html
DBusTypeWriter
*writer,
01888
const
structDBusString.html
DBusString
*contained_type,
01889
int
contained_type_start,
01890
int
contained_type_len,
01891
structDBusTypeWriter.html
DBusTypeWriter
*sub,
01892
group__DBusTypes.html#ga2
dbus_bool_t
is_array_append)
01893 {
01894
group__DBusTypes.html#ga3
dbus_uint32_t
value = 0;
01895
int
alignment;
01896
int
aligned;
01897
01898
#ifndef DBUS_DISABLE_CHECKS
01899
if
(writer->
structDBusTypeWriter.html#o1
container_type
== DBUS_TYPE_ARRAY &&
01900       writer->
structDBusTypeWriter.html#o4
type_str
)
01901     {
01902
if
(!
group__DBusString.html#ga50
_dbus_string_equal_substring
(contained_type,
01903                                          contained_type_start,
01904                                          contained_type_len,
01905                                          writer->
structDBusTypeWriter.html#o4
type_str
,
01906                                          writer->
structDBusTypeWriter.html#o12
u
.array.element_type_pos + 1))
01907         {
01908
group__DBusInternalsUtils.html#ga7
_dbus_warn
(
"Writing an array of '%s' but this is incompatible with the expected type of elements in the parent array\n"
,
01909                       _dbus_string_get_const_data_len (contained_type,
01910                                                        contained_type_start,
01911                                                        contained_type_len));
01912
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"incompatible type for child array"
);
01913         }
01914     }
01915
#endif
/* DBUS_DISABLE_CHECKS */
01916
01917
if
(writer->
structDBusTypeWriter.html#o3
enabled
&& !is_array_append)
01918     {
01919
/* 3 pad + 4 bytes for the array length, and 4 bytes possible padding
01920
* before array values
01921
*/
01922
if
(!
group__DBusString.html#ga25
_dbus_string_alloc_space
(sub->
structDBusTypeWriter.html#o6
value_str
, 3 + 4 + 4))
01923
return
group__DBusMacros.html#ga3
FALSE
;
01924     }
01925
01926
if
(writer->
structDBusTypeWriter.html#o4
type_str
!= NULL)
01927     {
01928       sub->
structDBusTypeWriter.html#o5
type_pos
+= 1;
/* move to point to the element type, since type_pos
01929
* should be the expected type for further writes
01930
*/
01931       sub->
structDBusTypeWriter.html#o12
u
.array.element_type_pos = sub->
structDBusTypeWriter.html#o5
type_pos
;
01932     }
01933
01934
if
(!writer->
structDBusTypeWriter.html#o2
type_pos_is_expectation
)
01935     {
01936
/* sub is a toplevel/outermost array so we need to write the type data */
01937
01938
/* alloc space for array typecode, element signature */
01939
if
(!
group__DBusString.html#ga25
_dbus_string_alloc_space
(writer->
structDBusTypeWriter.html#o4
type_str
, 1 + contained_type_len))
01940
return
group__DBusMacros.html#ga3
FALSE
;
01941
01942
if
(!
group__DBusString.html#ga15
_dbus_string_insert_byte
(writer->
structDBusTypeWriter.html#o4
type_str
,
01943                                      writer->
structDBusTypeWriter.html#o5
type_pos
,
01944                                      DBUS_TYPE_ARRAY))
01945
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"failed to insert array typecode after prealloc"
);
01946
01947
if
(!
group__DBusString.html#ga42
_dbus_string_copy_len
(contained_type,
01948                                   contained_type_start, contained_type_len,
01949                                   sub->
structDBusTypeWriter.html#o4
type_str
,
01950                                   sub->
structDBusTypeWriter.html#o12
u
.array.element_type_pos))
01951
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"should not have failed to insert array element typecodes"
);
01952     }
01953
01954
if
(writer->
structDBusTypeWriter.html#o4
type_str
!= NULL)
01955     {
01956
/* If the parent is an array, we hold type_pos pointing at the array element type;
01957
* otherwise advance it to reflect the array value we just recursed into
01958
*/
01959
if
(writer->
structDBusTypeWriter.html#o1
container_type
!= DBUS_TYPE_ARRAY)
01960         writer->
structDBusTypeWriter.html#o5
type_pos
+= 1 + contained_type_len;
01961
else
01962
group__DBusInternalsUtils.html#ga130
_dbus_assert
(writer->
structDBusTypeWriter.html#o2
type_pos_is_expectation
);
/* because it's an array */
01963     }
01964
01965
if
(writer->
structDBusTypeWriter.html#o3
enabled
)
01966     {
01967
/* Write (or jump over, if is_array_append) the length */
01968       sub->
structDBusTypeWriter.html#o12
u
.array.len_pos = _DBUS_ALIGN_VALUE (sub->
structDBusTypeWriter.html#o7
value_pos
, 4);
01969
01970
if
(is_array_append)
01971         {
01972           sub->
structDBusTypeWriter.html#o7
value_pos
+= 4;
01973         }
01974
else
01975         {
01976
if
(!_dbus_type_writer_write_basic_no_typecode (sub, DBUS_TYPE_UINT32,
01977                                                           &value))
01978
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"should not have failed to insert array len"
);
01979         }
01980
01981
group__DBusInternalsUtils.html#ga130
_dbus_assert
(sub->
structDBusTypeWriter.html#o12
u
.array.len_pos == sub->
structDBusTypeWriter.html#o7
value_pos
- 4);
01982
01983
/* Write alignment padding for array elements
01984
* Note that we write the padding *even for empty arrays*
01985
* to avoid wonky special cases
01986
*/
01987       alignment = element_type_get_alignment (contained_type, contained_type_start);
01988
01989       aligned = _DBUS_ALIGN_VALUE (sub->
structDBusTypeWriter.html#o7
value_pos
, alignment);
01990
if
(aligned != sub->
structDBusTypeWriter.html#o7
value_pos
)
01991         {
01992
if
(!is_array_append)
01993             {
01994
if
(!
group__DBusString.html#ga14
_dbus_string_insert_bytes
(sub->
structDBusTypeWriter.html#o6
value_str
,
01995                                               sub->
structDBusTypeWriter.html#o7
value_pos
,
01996                                               aligned - sub->
structDBusTypeWriter.html#o7
value_pos
,
01997
'\0'
))
01998
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"should not have failed to insert alignment padding"
);
01999             }
02000
02001           sub->
structDBusTypeWriter.html#o7
value_pos
= aligned;
02002         }
02003
02004       sub->
structDBusTypeWriter.html#o12
u
.array.start_pos = sub->
structDBusTypeWriter.html#o7
value_pos
;
02005
02006
if
(is_array_append)
02007         {
02008
group__DBusTypes.html#ga3
dbus_uint32_t
len;
02009
02010
group__DBusInternalsUtils.html#ga130
_dbus_assert
(_DBUS_ALIGN_VALUE (sub->
structDBusTypeWriter.html#o12
u
.array.len_pos, 4) ==
02011                         (
unsigned
) sub->
structDBusTypeWriter.html#o12
u
.array.len_pos);
02012           len = _dbus_unpack_uint32 (sub->
structDBusTypeWriter.html#o0
byte_order
,
02013                                      _dbus_string_get_const_data_len (sub->
structDBusTypeWriter.html#o6
value_str
,
02014                                                                       sub->
structDBusTypeWriter.html#o12
u
.array.len_pos,
02015                                                                       4));
02016
02017           sub->
structDBusTypeWriter.html#o7
value_pos
+= len;
02018         }
02019     }
02020
else
02021     {
02022
/* not enabled, so we won't write the len_pos; set it to -1 to so indicate */
02023       sub->
structDBusTypeWriter.html#o12
u
.array.len_pos = -1;
02024       sub->
structDBusTypeWriter.html#o12
u
.array.start_pos = sub->
structDBusTypeWriter.html#o7
value_pos
;
02025     }
02026
02027
group__DBusInternalsUtils.html#ga130
_dbus_assert
(sub->
structDBusTypeWriter.html#o12
u
.array.len_pos < sub->
structDBusTypeWriter.html#o12
u
.array.start_pos);
02028
group__DBusInternalsUtils.html#ga130
_dbus_assert
(is_array_append || sub->
structDBusTypeWriter.html#o12
u
.array.start_pos == sub->
structDBusTypeWriter.html#o7
value_pos
);
02029
02030
#if RECURSIVE_MARSHAL_WRITE_TRACE
02031
_dbus_verbose (
"  type writer %p recurse array done remaining sig '%s' array start_pos = %d len_pos = %d value_pos = %d\n"
, sub,
02032                      sub->
structDBusTypeWriter.html#o4
type_str
?
02033                      _dbus_string_get_const_data_len (sub->
structDBusTypeWriter.html#o4
type_str
, sub->
structDBusTypeWriter.html#o5
type_pos
, 0) :
02034
"unknown"
,
02035                      sub->
structDBusTypeWriter.html#o12
u
.array.start_pos, sub->
structDBusTypeWriter.html#o12
u
.array.len_pos, sub->
structDBusTypeWriter.html#o7
value_pos
);
02036
#endif
02037
02038
return
group__DBusMacros.html#ga2
TRUE
;
02039 }
02040
02041
/* Variant value will normally have:
02042
*   1 byte signature length not including nul
02043
*   signature typecodes (nul terminated)
02044
*   padding to alignment of contained type
02045
*   body according to signature
02046
*
02047
* The signature string can only have a single type
02048
* in it but that type may be complex/recursive.
02049
*
02050
* So a typical variant type with the integer 3 will have these
02051
* octets:
02052
*   0x1 'i' '\0' [1 byte padding to alignment boundary] 0x0 0x0 0x0 0x3
02053
*
02054
* The main world of hurt for writing out a variant is that the type
02055
* string is the same string as the value string. Which means
02056
* inserting to the type string will move the value_pos; and it means
02057
* that inserting to the type string could break type alignment.
02058
*/
02059
static
group__DBusTypes.html#ga2
dbus_bool_t
02060 writer_recurse_variant (
structDBusTypeWriter.html
DBusTypeWriter
*writer,
02061
const
structDBusString.html
DBusString
*contained_type,
02062
int
contained_type_start,
02063
int
contained_type_len,
02064
structDBusTypeWriter.html
DBusTypeWriter
*sub)
02065 {
02066
int
contained_alignment;
02067
02068
if
(writer->
structDBusTypeWriter.html#o3
enabled
)
02069     {
02070
/* Allocate space for the worst case, which is 1 byte sig
02071
* length, nul byte at end of sig, and 7 bytes padding to
02072
* 8-boundary.
02073
*/
02074
if
(!
group__DBusString.html#ga25
_dbus_string_alloc_space
(sub->
structDBusTypeWriter.html#o6
value_str
, contained_type_len + 9))
02075
return
group__DBusMacros.html#ga3
FALSE
;
02076     }
02077
02078
/* write VARIANT typecode to the parent's type string */
02079
if
(!write_or_verify_typecode (writer, DBUS_TYPE_VARIANT))
02080
return
group__DBusMacros.html#ga3
FALSE
;
02081
02082
/* If not enabled, mark that we have no type_str anymore ... */
02083
02084
if
(!writer->enabled)
02085     {
02086       sub->
structDBusTypeWriter.html#o4
type_str
= NULL;
02087       sub->
structDBusTypeWriter.html#o5
type_pos
= -1;
02088
02089
return
group__DBusMacros.html#ga2
TRUE
;
02090     }
02091
02092
/* If we're enabled then continue ... */
02093
02094
if
(!
group__DBusString.html#ga15
_dbus_string_insert_byte
(sub->
structDBusTypeWriter.html#o6
value_str
,
02095                                  sub->
structDBusTypeWriter.html#o7
value_pos
,
02096                                  contained_type_len))
02097
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"should not have failed to insert variant type sig len"
);
02098
02099   sub->
structDBusTypeWriter.html#o7
value_pos
+= 1;
02100
02101
/* Here we switch over to the expected type sig we're about to write */
02102   sub->
structDBusTypeWriter.html#o4
type_str
= sub->
structDBusTypeWriter.html#o6
value_str
;
02103   sub->
structDBusTypeWriter.html#o5
type_pos
= sub->
structDBusTypeWriter.html#o7
value_pos
;
02104
02105
if
(!
group__DBusString.html#ga42
_dbus_string_copy_len
(contained_type, contained_type_start, contained_type_len,
02106                               sub->
structDBusTypeWriter.html#o6
value_str
, sub->
structDBusTypeWriter.html#o7
value_pos
))
02107
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"should not have failed to insert variant type sig"
);
02108
02109   sub->
structDBusTypeWriter.html#o7
value_pos
+= contained_type_len;
02110
02111
if
(!
group__DBusString.html#ga15
_dbus_string_insert_byte
(sub->
structDBusTypeWriter.html#o6
value_str
,
02112                                  sub->
structDBusTypeWriter.html#o7
value_pos
,
02113                                  DBUS_TYPE_INVALID))
02114
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"should not have failed to insert variant type nul termination"
);
02115
02116   sub->
structDBusTypeWriter.html#o7
value_pos
+= 1;
02117
02118   contained_alignment =
group__DBusMarshal.html#ga40
_dbus_type_get_alignment
(
group__DBusMarshal.html#ga46
_dbus_first_type_in_signature
(contained_type, contained_type_start));
02119
02120
if
(!
group__DBusString.html#ga14
_dbus_string_insert_bytes
(sub->
structDBusTypeWriter.html#o6
value_str
,
02121                                   sub->
structDBusTypeWriter.html#o7
value_pos
,
02122                                   _DBUS_ALIGN_VALUE (sub->
structDBusTypeWriter.html#o7
value_pos
, contained_alignment) - sub->
structDBusTypeWriter.html#o7
value_pos
,
02123
'\0'
))
02124
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"should not have failed to insert alignment padding for variant body"
);
02125   sub->
structDBusTypeWriter.html#o7
value_pos
= _DBUS_ALIGN_VALUE (sub->
structDBusTypeWriter.html#o7
value_pos
, contained_alignment);
02126
02127
return
group__DBusMacros.html#ga2
TRUE
;
02128 }
02129
02130
static
group__DBusTypes.html#ga2
dbus_bool_t
02131 _dbus_type_writer_recurse_contained_len (
structDBusTypeWriter.html
DBusTypeWriter
*writer,
02132
int
container_type,
02133
const
structDBusString.html
DBusString
*contained_type,
02134
int
contained_type_start,
02135
int
contained_type_len,
02136
structDBusTypeWriter.html
DBusTypeWriter
*sub,
02137
group__DBusTypes.html#ga2
dbus_bool_t
is_array_append)
02138 {
02139   writer_recurse_init_and_check (writer, container_type, sub);
02140
02141
switch
(container_type)
02142     {
02143
case
DBUS_TYPE_STRUCT:
02144
return
writer_recurse_struct_or_dict_entry (writer,
02145                                                   DBUS_STRUCT_BEGIN_CHAR,
02146                                                   contained_type,
02147                                                   contained_type_start, contained_type_len,
02148                                                   sub);
02149
break
;
02150
case
DBUS_TYPE_DICT_ENTRY:
02151
return
writer_recurse_struct_or_dict_entry (writer,
02152                                                   DBUS_DICT_ENTRY_BEGIN_CHAR,
02153                                                   contained_type,
02154                                                   contained_type_start, contained_type_len,
02155                                                   sub);
02156
break
;
02157
case
DBUS_TYPE_ARRAY:
02158
return
writer_recurse_array (writer,
02159                                    contained_type, contained_type_start, contained_type_len,
02160                                    sub, is_array_append);
02161
break
;
02162
case
DBUS_TYPE_VARIANT:
02163
return
writer_recurse_variant (writer,
02164                                      contained_type, contained_type_start, contained_type_len,
02165                                      sub);
02166
break
;
02167
default
:
02168
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"tried to recurse into type that doesn't support that"
);
02169
return
group__DBusMacros.html#ga3
FALSE
;
02170
break
;
02171     }
02172 }
02173
02184
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusMarshal.html#ga140
02185
group__DBusMarshal.html#ga140
_dbus_type_writer_recurse
(
structDBusTypeWriter.html
DBusTypeWriter
*writer,
02186
int
container_type,
02187
const
structDBusString.html
DBusString
*contained_type,
02188
int
contained_type_start,
02189
structDBusTypeWriter.html
DBusTypeWriter
*sub)
02190 {
02191
int
contained_type_len;
02192
02193
if
(contained_type)
02194     contained_type_len = find_len_of_complete_type (contained_type, contained_type_start);
02195
else
02196     contained_type_len = 0;
02197
02198
return
_dbus_type_writer_recurse_contained_len (writer, container_type,
02199                                                   contained_type,
02200                                                   contained_type_start,
02201                                                   contained_type_len,
02202                                                   sub,
02203
group__DBusMacros.html#ga3
FALSE
);
02204 }
02205
02218
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusMarshal.html#ga141
02219
group__DBusMarshal.html#ga141
_dbus_type_writer_append_array
(
structDBusTypeWriter.html
DBusTypeWriter
*writer,
02220
const
structDBusString.html
DBusString
*contained_type,
02221
int
contained_type_start,
02222
structDBusTypeWriter.html
DBusTypeWriter
*sub)
02223 {
02224
int
contained_type_len;
02225
02226
if
(contained_type)
02227     contained_type_len = find_len_of_complete_type (contained_type, contained_type_start);
02228
else
02229     contained_type_len = 0;
02230
02231
return
_dbus_type_writer_recurse_contained_len (writer, DBUS_TYPE_ARRAY,
02232                                                   contained_type,
02233                                                   contained_type_start,
02234                                                   contained_type_len,
02235                                                   sub,
02236
group__DBusMacros.html#ga2
TRUE
);
02237 }
02238
02239
static
int
02240 writer_get_array_len (
structDBusTypeWriter.html
DBusTypeWriter
*writer)
02241 {
02242
group__DBusInternalsUtils.html#ga130
_dbus_assert
(writer->
structDBusTypeWriter.html#o1
container_type
== DBUS_TYPE_ARRAY);
02243
return
writer->
structDBusTypeWriter.html#o7
value_pos
- writer->
structDBusTypeWriter.html#o12
u
.array.start_pos;
02244 }
02245
02254
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusMarshal.html#ga143
02255
group__DBusMarshal.html#ga143
_dbus_type_writer_unrecurse
(
structDBusTypeWriter.html
DBusTypeWriter
*writer,
02256
structDBusTypeWriter.html
DBusTypeWriter
*sub)
02257 {
02258
/* type_pos_is_expectation never gets unset once set, or we'd get all hosed */
02259
group__DBusInternalsUtils.html#ga130
_dbus_assert
(!writer->
structDBusTypeWriter.html#o2
type_pos_is_expectation
||
02260                 (writer->
structDBusTypeWriter.html#o2
type_pos_is_expectation
&& sub->
structDBusTypeWriter.html#o2
type_pos_is_expectation
));
02261
02262
#if RECURSIVE_MARSHAL_WRITE_TRACE
02263
_dbus_verbose (
"  type writer %p unrecurse type_pos = %d value_pos = %d is_expectation = %d container_type = %s\n"
,
02264                  writer, writer->
structDBusTypeWriter.html#o5
type_pos
, writer->
structDBusTypeWriter.html#o7
value_pos
, writer->
structDBusTypeWriter.html#o2
type_pos_is_expectation
,
02265
group__DBusMarshal.html#ga42
_dbus_type_to_string
(writer->
structDBusTypeWriter.html#o1
container_type
));
02266   _dbus_verbose (
"  type writer %p unrecurse sub type_pos = %d value_pos = %d is_expectation = %d container_type = %s\n"
,
02267                  sub, sub->
structDBusTypeWriter.html#o5
type_pos
, sub->
structDBusTypeWriter.html#o7
value_pos
,
02268                  sub->
structDBusTypeWriter.html#o2
type_pos_is_expectation
,
02269
group__DBusMarshal.html#ga42
_dbus_type_to_string
(sub->
structDBusTypeWriter.html#o1
container_type
));
02270
#endif
02271
02272
if
(sub->
structDBusTypeWriter.html#o1
container_type
== DBUS_TYPE_STRUCT)
02273     {
02274
if
(!write_or_verify_typecode (sub, DBUS_STRUCT_END_CHAR))
02275
return
group__DBusMacros.html#ga3
FALSE
;
02276     }
02277
else
if
(sub->
structDBusTypeWriter.html#o1
container_type
== DBUS_TYPE_DICT_ENTRY)
02278     {
02279
if
(!write_or_verify_typecode (sub, DBUS_DICT_ENTRY_END_CHAR))
02280
return
group__DBusMacros.html#ga3
FALSE
;
02281     }
02282
else
if
(sub->
structDBusTypeWriter.html#o1
container_type
== DBUS_TYPE_ARRAY)
02283     {
02284
if
(sub->
structDBusTypeWriter.html#o12
u
.array.len_pos >= 0)
/* len_pos == -1 if we weren't enabled when we passed it */
02285         {
02286
group__DBusTypes.html#ga3
dbus_uint32_t
len;
02287
02288
/* Set the array length */
02289           len = writer_get_array_len (sub);
02290
group__DBusMarshal.html#ga19
_dbus_marshal_set_uint32
(sub->
structDBusTypeWriter.html#o6
value_str
,
02291                                     sub->
structDBusTypeWriter.html#o12
u
.array.len_pos,
02292                                     len,
02293                                     sub->
structDBusTypeWriter.html#o0
byte_order
);
02294
#if RECURSIVE_MARSHAL_WRITE_TRACE
02295
_dbus_verbose (
"    filled in sub array len to %u at len_pos %d\n"
,
02296                          len, sub->
structDBusTypeWriter.html#o12
u
.array.len_pos);
02297
#endif
02298
}
02299
#if RECURSIVE_MARSHAL_WRITE_TRACE
02300
else
02301         {
02302           _dbus_verbose (
"    not filling in sub array len because we were disabled when we passed the len\n"
);
02303         }
02304
#endif
02305
}
02306
02307
/* Now get type_pos right for the parent writer. Here are the cases:
02308
*
02309
* Cases !writer->type_pos_is_expectation:
02310
*   (in these cases we want to update to the new insertion point)
02311
*
02312
* - if we recursed into a STRUCT then we didn't know in advance
02313
*   what the types in the struct would be; so we have to fill in
02314
*   that information now.
02315
*       writer->type_pos = sub->type_pos
02316
*
02317
* - if we recursed into anything else, we knew the full array
02318
*   type, or knew the single typecode marking VARIANT, so
02319
*   writer->type_pos is already correct.
02320
*       writer->type_pos should remain as-is
02321
*
02322
* - note that the parent is never an ARRAY or VARIANT, if it were
02323
*   then type_pos_is_expectation would be TRUE. The parent
02324
*   is thus known to be a toplevel or STRUCT.
02325
*
02326
* Cases where writer->type_pos_is_expectation:
02327
*   (in these cases we want to update to next expected type to write)
02328
*
02329
* - we recursed from STRUCT into STRUCT and we didn't increment
02330
*   type_pos in the parent just to stay consistent with the
02331
*   !writer->type_pos_is_expectation case (though we could
02332
*   special-case this in recurse_struct instead if we wanted)
02333
*       writer->type_pos = sub->type_pos
02334
*
02335
* - we recursed from STRUCT into ARRAY or VARIANT and type_pos
02336
*   for parent should have been incremented already
02337
*       writer->type_pos should remain as-is
02338
*
02339
* - we recursed from ARRAY into a sub-element, so type_pos in the
02340
*   parent is the element type and should remain the element type
02341
*   for the benefit of the next child element
02342
*       writer->type_pos should remain as-is
02343
*
02344
* - we recursed from VARIANT into its value, so type_pos in the
02345
*   parent makes no difference since there's only one value
02346
*   and we just finished writing it and won't use type_pos again
02347
*       writer->type_pos should remain as-is
02348
*
02349
*
02350
* For all these, DICT_ENTRY is the same as STRUCT
02351
*/
02352
if
(writer->
structDBusTypeWriter.html#o4
type_str
!= NULL)
02353     {
02354
if
((sub->
structDBusTypeWriter.html#o1
container_type
== DBUS_TYPE_STRUCT ||
02355            sub->
structDBusTypeWriter.html#o1
container_type
== DBUS_TYPE_DICT_ENTRY) &&
02356           (writer->
structDBusTypeWriter.html#o1
container_type
== DBUS_TYPE_STRUCT ||
02357            writer->
structDBusTypeWriter.html#o1
container_type
== DBUS_TYPE_DICT_ENTRY ||
02358            writer->
structDBusTypeWriter.html#o1
container_type
== DBUS_TYPE_INVALID))
02359         {
02360
/* Advance the parent to the next struct field */
02361           writer->
structDBusTypeWriter.html#o5
type_pos
= sub->
structDBusTypeWriter.html#o5
type_pos
;
02362         }
02363     }
02364
02365   writer->
structDBusTypeWriter.html#o7
value_pos
= sub->
structDBusTypeWriter.html#o7
value_pos
;
02366
02367
#if RECURSIVE_MARSHAL_WRITE_TRACE
02368
_dbus_verbose (
"  type writer %p unrecursed type_pos = %d value_pos = %d remaining sig '%s'\n"
,
02369                  writer, writer->
structDBusTypeWriter.html#o5
type_pos
, writer->
structDBusTypeWriter.html#o7
value_pos
,
02370                  writer->
structDBusTypeWriter.html#o4
type_str
?
02371                  _dbus_string_get_const_data_len (writer->
structDBusTypeWriter.html#o4
type_str
, writer->
structDBusTypeWriter.html#o5
type_pos
, 0) :
02372
"unknown"
);
02373
#endif
02374
02375
return
group__DBusMacros.html#ga2
TRUE
;
02376 }
02377
02386
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusMarshal.html#ga144
02387
group__DBusMarshal.html#ga144
_dbus_type_writer_write_basic
(
structDBusTypeWriter.html
DBusTypeWriter
*writer,
02388
int
type,
02389
const
void
*value)
02390 {
02391
group__DBusTypes.html#ga2
dbus_bool_t
retval;
02392
02393
/* First ensure that our type realloc will succeed */
02394
if
(!writer->
structDBusTypeWriter.html#o2
type_pos_is_expectation
&& writer->
structDBusTypeWriter.html#o4
type_str
!= NULL)
02395     {
02396
if
(!
group__DBusString.html#ga25
_dbus_string_alloc_space
(writer->
structDBusTypeWriter.html#o4
type_str
, 1))
02397
return
group__DBusMacros.html#ga3
FALSE
;
02398     }
02399
02400   retval =
group__DBusMacros.html#ga3
FALSE
;
02401
02402
if
(!_dbus_type_writer_write_basic_no_typecode (writer, type, value))
02403
goto
out;
02404
02405
if
(!write_or_verify_typecode (writer, type))
02406
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"failed to write typecode after prealloc"
);
02407
02408   retval =
group__DBusMacros.html#ga2
TRUE
;
02409
02410  out:
02411
#if RECURSIVE_MARSHAL_WRITE_TRACE
02412
_dbus_verbose (
"  type writer %p basic type_pos = %d value_pos = %d is_expectation = %d enabled = %d\n"
,
02413                  writer, writer->type_pos, writer->value_pos, writer->type_pos_is_expectation,
02414                  writer->enabled);
02415
#endif
02416
02417
return
retval;
02418 }
02419
02434
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusMarshal.html#ga145
02435
group__DBusMarshal.html#ga145
_dbus_type_writer_write_fixed_multi
(
structDBusTypeWriter.html
DBusTypeWriter
*writer,
02436
int
element_type,
02437
const
void
*value,
02438
int
n_elements)
02439 {
02440
group__DBusInternalsUtils.html#ga130
_dbus_assert
(writer->
structDBusTypeWriter.html#o1
container_type
== DBUS_TYPE_ARRAY);
02441
group__DBusInternalsUtils.html#ga130
_dbus_assert
(
group__DBusSignature.html#ga10
dbus_type_is_fixed
(element_type));
02442
group__DBusInternalsUtils.html#ga130
_dbus_assert
(writer->
structDBusTypeWriter.html#o2
type_pos_is_expectation
);
02443
group__DBusInternalsUtils.html#ga130
_dbus_assert
(n_elements >= 0);
02444
02445
#if RECURSIVE_MARSHAL_WRITE_TRACE
02446
_dbus_verbose (
"  type writer %p entering fixed multi type_pos = %d value_pos = %d n_elements %d\n"
,
02447                  writer, writer->
structDBusTypeWriter.html#o5
type_pos
, writer->
structDBusTypeWriter.html#o7
value_pos
, n_elements);
02448
#endif
02449
02450
if
(!write_or_verify_typecode (writer, element_type))
02451
group__DBusInternalsUtils.html#ga131
_dbus_assert_not_reached
(
"OOM should not happen if only verifying typecode"
);
02452
02453
if
(writer->enabled)
02454     {
02455
if
(!
group__DBusMarshal.html#ga37
_dbus_marshal_write_fixed_multi
(writer->value_str,
02456                                             writer->value_pos,
02457                                             element_type,
02458                                             value,
02459                                             n_elements,
02460                                             writer->byte_order,
02461                                             &writer->value_pos))
02462
return
group__DBusMacros.html#ga3
FALSE
;
02463     }
02464
02465
#if RECURSIVE_MARSHAL_WRITE_TRACE
02466
_dbus_verbose (
"  type writer %p fixed multi written new type_pos = %d new value_pos = %d n_elements %d\n"
,
02467                  writer, writer->type_pos, writer->value_pos, n_elements);
02468
#endif
02469
02470
return
group__DBusMacros.html#ga2
TRUE
;
02471 }
02472
02473
static
void
02474 enable_if_after (
structDBusTypeWriter.html
DBusTypeWriter
*writer,
02475
structDBusTypeReader.html
DBusTypeReader
*reader,
02476
const
structDBusTypeReader.html
DBusTypeReader
*start_after)
02477 {
02478
if
(start_after)
02479     {
02480
if
(!writer->
structDBusTypeWriter.html#o3
enabled
&&
group__DBusMarshal.html#ga127
_dbus_type_reader_greater_than
(reader, start_after))
02481         {
02482
group__DBusMarshal.html#ga151
_dbus_type_writer_set_enabled
(writer,
group__DBusMacros.html#ga2
TRUE
);
02483
#if RECURSIVE_MARSHAL_WRITE_TRACE
02484
_dbus_verbose (
"ENABLING writer %p at %d because reader at value_pos %d is after reader at value_pos %d\n"
,
02485                          writer, writer->
structDBusTypeWriter.html#o7
value_pos
, reader->
structDBusTypeReader.html#o6
value_pos
, start_after->
structDBusTypeReader.html#o6
value_pos
);
02486
#endif
02487
}
02488
02489
group__DBusInternalsUtils.html#ga130
_dbus_assert
((!writer->
structDBusTypeWriter.html#o3
enabled
&& !
group__DBusMarshal.html#ga127
_dbus_type_reader_greater_than
(reader, start_after)) ||
02490                     (writer->
structDBusTypeWriter.html#o3
enabled
&&
group__DBusMarshal.html#ga127
_dbus_type_reader_greater_than
(reader, start_after)));
02491     }
02492 }
02493
02494
static
group__DBusTypes.html#ga2
dbus_bool_t
02495 append_fixup (
structDBusList.html
DBusList
**fixups,
02496
const
structDBusArrayLenFixup.html
DBusArrayLenFixup
*fixup)
02497 {
02498
structDBusArrayLenFixup.html
DBusArrayLenFixup
*f;
02499
02500   f =
group__DBusMemory.html#ga6
dbus_new
(
structDBusArrayLenFixup.html
DBusArrayLenFixup
, 1);
02501
if
(f == NULL)
02502
return
group__DBusMacros.html#ga3
FALSE
;
02503
02504   *f = *fixup;
02505
02506
if
(!
group__DBusList.html#ga2
_dbus_list_append
(fixups, f))
02507     {
02508
group__DBusMemory.html#ga3
dbus_free
(f);
02509
return
group__DBusMacros.html#ga3
FALSE
;
02510     }
02511
02512
group__DBusInternalsUtils.html#ga130
_dbus_assert
(f->
structDBusArrayLenFixup.html#o0
len_pos_in_reader
== fixup->
structDBusArrayLenFixup.html#o0
len_pos_in_reader
);
02513
group__DBusInternalsUtils.html#ga130
_dbus_assert
(f->
structDBusArrayLenFixup.html#o1
new_len
== fixup->
structDBusArrayLenFixup.html#o1
new_len
);
02514
02515
return
group__DBusMacros.html#ga2
TRUE
;
02516 }
02517
02518
/* This loop is trivial if you ignore all the start_after nonsense,
02519
* so if you're trying to figure it out, start by ignoring that
02520
*/
02521
static
group__DBusTypes.html#ga2
dbus_bool_t
02522 writer_write_reader_helper (
structDBusTypeWriter.html
DBusTypeWriter
*writer,
02523
structDBusTypeReader.html
DBusTypeReader
*reader,
02524
const
structDBusTypeReader.html
DBusTypeReader
*start_after,
02525
int
start_after_new_pos,
02526
int
start_after_new_len,
02527
structDBusList.html
DBusList
**fixups,
02528
group__DBusTypes.html#ga2
dbus_bool_t
inside_start_after)
02529 {
02530
int
current_type;
02531
02532
while
((current_type =
group__DBusMarshal.html#ga109
_dbus_type_reader_get_current_type
(reader)) != DBUS_TYPE_INVALID)
02533     {
02534
if
(
group__DBusSignature.html#ga8
dbus_type_is_container
(current_type))
02535         {
02536
structDBusTypeReader.html
DBusTypeReader
subreader;
02537
structDBusTypeWriter.html
DBusTypeWriter
subwriter;
02538
const
structDBusString.html
DBusString
*sig_str;
02539
int
sig_start;
02540
int
sig_len;
02541
group__DBusTypes.html#ga2
dbus_bool_t
enabled_at_recurse;
02542
group__DBusTypes.html#ga2
dbus_bool_t
past_start_after;
02543
int
reader_array_len_pos;
02544
int
reader_array_start_pos;
02545
group__DBusTypes.html#ga2
dbus_bool_t
this_is_start_after;
02546
02547
/* type_pos is checked since e.g. in a struct the struct
02548
* and its first field have the same value_pos.
02549
* type_str will differ in reader/start_after for variants
02550
* where type_str is inside the value_str
02551
*/
02552
if
(!inside_start_after && start_after &&
02553               reader->
structDBusTypeReader.html#o6
value_pos
== start_after->
structDBusTypeReader.html#o6
value_pos
&&
02554               reader->type_str == start_after->
structDBusTypeReader.html#o3
type_str
&&
02555               reader->type_pos == start_after->
structDBusTypeReader.html#o4
type_pos
)
02556             this_is_start_after =
group__DBusMacros.html#ga2
TRUE
;
02557
else
02558             this_is_start_after =
group__DBusMacros.html#ga3
FALSE
;
02559
02560
group__DBusMarshal.html#ga116
_dbus_type_reader_recurse
(reader, &subreader);
02561
02562
if
(current_type == DBUS_TYPE_ARRAY)
02563             {
02564               reader_array_len_pos =
group__DBusMarshal.html#ga183
ARRAY_READER_LEN_POS
(&subreader);
02565               reader_array_start_pos = subreader.
structDBusTypeReader.html#o10
u
.array.start_pos;
02566             }
02567
else
02568             {
02569
/* quiet gcc */
02570               reader_array_len_pos = -1;
02571               reader_array_start_pos = -1;
02572             }
02573
02574
group__DBusMarshal.html#ga119
_dbus_type_reader_get_signature
(&subreader, &sig_str,
02575                                            &sig_start, &sig_len);
02576
02577
#if RECURSIVE_MARSHAL_WRITE_TRACE
02578
_dbus_verbose (
"about to recurse into %s reader at %d subreader at %d writer at %d start_after reader at %d write target len %d inside_start_after = %d this_is_start_after = %d\n"
,
02579
group__DBusMarshal.html#ga42
_dbus_type_to_string
(current_type),
02580                          reader->value_pos,
02581                          subreader.
structDBusTypeReader.html#o6
value_pos
,
02582                          writer->
structDBusTypeWriter.html#o7
value_pos
,
02583                          start_after ? start_after->
structDBusTypeReader.html#o6
value_pos
: -1,
02584                          _dbus_string_get_length (writer->
structDBusTypeWriter.html#o6
value_str
),
02585                          inside_start_after, this_is_start_after);
02586
#endif
02587
02588
if
(!inside_start_after && !this_is_start_after)
02589             enable_if_after (writer, &subreader, start_after);
02590           enabled_at_recurse = writer->
structDBusTypeWriter.html#o3
enabled
;
02591
if
(!_dbus_type_writer_recurse_contained_len (writer, current_type,
02592                                                         sig_str, sig_start, sig_len,
02593                                                         &subwriter,
group__DBusMacros.html#ga3
FALSE
))
02594
goto
oom;
02595
02596
#if RECURSIVE_MARSHAL_WRITE_TRACE
02597
_dbus_verbose (
"recursed into subwriter at %d write target len %d\n"
,
02598                          subwriter.
structDBusTypeWriter.html#o7
value_pos
,
02599                          _dbus_string_get_length (subwriter.
structDBusTypeWriter.html#o6
value_str
));
02600
#endif
02601
02602
if
(!writer_write_reader_helper (&subwriter, &subreader, start_after,
02603                                            start_after_new_pos, start_after_new_len,
02604                                            fixups,
02605                                            inside_start_after ||
02606                                            this_is_start_after))
02607
goto
oom;
02608
02609
#if RECURSIVE_MARSHAL_WRITE_TRACE
02610
_dbus_verbose (
"about to unrecurse from %s subreader at %d writer at %d subwriter at %d  write target len %d\n"
,
02611
group__DBusMarshal.html#ga42
_dbus_type_to_string
(current_type),
02612                          subreader.
structDBusTypeReader.html#o6
value_pos
,
02613                          writer->value_pos,
02614                          subwriter.value_pos,
02615                          _dbus_string_get_length (writer->value_str));
02616
#endif
02617
02618
if
(!inside_start_after && !this_is_start_after)
02619             enable_if_after (writer, &subreader, start_after);
02620           past_start_after = writer->enabled;
02621
if
(!
group__DBusMarshal.html#ga143
_dbus_type_writer_unrecurse
(writer, &subwriter))
02622
goto
oom;
02623
02624
/* If we weren't enabled when we recursed, we didn't
02625
* write an array len; if we passed start_after
02626
* somewhere inside the array, then we need to generate
02627
* a fixup.
02628
*/
02629
if
(start_after != NULL &&
02630               !enabled_at_recurse && past_start_after &&
02631               current_type == DBUS_TYPE_ARRAY &&
02632               fixups != NULL)
02633             {
02634
structDBusArrayLenFixup.html
DBusArrayLenFixup
fixup;
02635
int
bytes_written_after_start_after;
02636
int
bytes_before_start_after;
02637
int
old_len;
02638
02639
/* this subwriter access is moderately unkosher since we
02640
* already unrecursed, but it works as long as unrecurse
02641
* doesn't break us on purpose
02642
*/
02643               bytes_written_after_start_after = writer_get_array_len (&subwriter);
02644
02645               bytes_before_start_after =
02646                 start_after->
structDBusTypeReader.html#o6
value_pos
- reader_array_start_pos;
02647
02648               fixup.
structDBusArrayLenFixup.html#o0
len_pos_in_reader
= reader_array_len_pos;
02649               fixup.
structDBusArrayLenFixup.html#o1
new_len
=
02650                 bytes_before_start_after +
02651                 start_after_new_len +
02652                 bytes_written_after_start_after;
02653
02654
group__DBusInternalsUtils.html#ga130
_dbus_assert
(_DBUS_ALIGN_VALUE (fixup.
structDBusArrayLenFixup.html#o0
len_pos_in_reader
, 4) ==
02655                             (
unsigned
) fixup.
structDBusArrayLenFixup.html#o0
len_pos_in_reader
);
02656
02657               old_len = _dbus_unpack_uint32 (reader->byte_order,
02658                                              _dbus_string_get_const_data_len (reader->value_str,
02659                                                                               fixup.
structDBusArrayLenFixup.html#o0
len_pos_in_reader
, 4));
02660
02661
if
(old_len != fixup.
structDBusArrayLenFixup.html#o1
new_len
&& !append_fixup (fixups, &fixup))
02662
goto
oom;
02663
02664
#if RECURSIVE_MARSHAL_WRITE_TRACE
02665
_dbus_verbose (
"Generated fixup len_pos_in_reader = %d new_len = %d reader_array_start_pos = %d start_after->value_pos = %d bytes_before_start_after = %d start_after_new_len = %d bytes_written_after_start_after = %d\n"
,
02666                              fixup.
structDBusArrayLenFixup.html#o0
len_pos_in_reader
,
02667                              fixup.
structDBusArrayLenFixup.html#o1
new_len
,
02668                              reader_array_start_pos,
02669                              start_after->
structDBusTypeReader.html#o6
value_pos
,
02670                              bytes_before_start_after,
02671                              start_after_new_len,
02672                              bytes_written_after_start_after);
02673
#endif
02674
}
02675         }
02676
else
02677         {
02678
unionDBusBasicValue.html
DBusBasicValue
val;
02679
02680
group__DBusInternalsUtils.html#ga130
_dbus_assert
(
group__DBusSignature.html#ga9
dbus_type_is_basic
(current_type));
02681
02682
#if RECURSIVE_MARSHAL_WRITE_TRACE
02683
_dbus_verbose (
"Reading basic value %s at %d\n"
,
02684
group__DBusMarshal.html#ga42
_dbus_type_to_string
(current_type),
02685                          reader->value_pos);
02686
#endif
02687
02688
group__DBusMarshal.html#ga113
_dbus_type_reader_read_basic
(reader, &val);
02689
02690
#if RECURSIVE_MARSHAL_WRITE_TRACE
02691
_dbus_verbose (
"Writing basic value %s at %d write target len %d inside_start_after = %d\n"
,
02692
group__DBusMarshal.html#ga42
_dbus_type_to_string
(current_type),
02693                          writer->value_pos,
02694                          _dbus_string_get_length (writer->value_str),
02695                          inside_start_after);
02696
#endif
02697
if
(!inside_start_after)
02698             enable_if_after (writer, reader, start_after);
02699
if
(!
group__DBusMarshal.html#ga144
_dbus_type_writer_write_basic
(writer, current_type, &val))
02700
goto
oom;
02701
#if RECURSIVE_MARSHAL_WRITE_TRACE
02702
_dbus_verbose (
"Wrote basic value %s, new value_pos %d write target len %d\n"
,
02703
group__DBusMarshal.html#ga42
_dbus_type_to_string
(current_type),
02704                          writer->value_pos,
02705                          _dbus_string_get_length (writer->value_str));
02706
#endif
02707
}
02708
02709
group__DBusMarshal.html#ga117
_dbus_type_reader_next
(reader);
02710     }
02711
02712
return
group__DBusMacros.html#ga2
TRUE
;
02713
02714  oom:
02715
if
(fixups)
02716     apply_and_free_fixups (fixups, NULL);
/* NULL for reader to apply to */
02717
02718
return
group__DBusMacros.html#ga3
FALSE
;
02719 }
02720
02752
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusMarshal.html#ga149
02753
group__DBusMarshal.html#ga149
_dbus_type_writer_write_reader_partial
(
structDBusTypeWriter.html
DBusTypeWriter
*writer,
02754
structDBusTypeReader.html
DBusTypeReader
*reader,
02755
const
structDBusTypeReader.html
DBusTypeReader
*start_after,
02756
int
start_after_new_pos,
02757
int
start_after_new_len,
02758
structDBusList.html
DBusList
**fixups)
02759 {
02760
structDBusTypeWriter.html
DBusTypeWriter
orig;
02761
int
orig_type_len;
02762
int
orig_value_len;
02763
int
new_bytes;
02764
int
orig_enabled;
02765
02766   orig = *writer;
02767   orig_type_len = _dbus_string_get_length (writer->
structDBusTypeWriter.html#o4
type_str
);
02768   orig_value_len = _dbus_string_get_length (writer->
structDBusTypeWriter.html#o6
value_str
);
02769   orig_enabled = writer->
structDBusTypeWriter.html#o3
enabled
;
02770
02771
if
(start_after)
02772
group__DBusMarshal.html#ga151
_dbus_type_writer_set_enabled
(writer,
group__DBusMacros.html#ga3
FALSE
);
02773
02774
if
(!writer_write_reader_helper (writer, reader, start_after,
02775                                    start_after_new_pos,
02776                                    start_after_new_len,
02777                                    fixups,
group__DBusMacros.html#ga3
FALSE
))
02778
goto
oom;
02779
02780
group__DBusMarshal.html#ga151
_dbus_type_writer_set_enabled
(writer, orig_enabled);
02781
return
group__DBusMacros.html#ga2
TRUE
;
02782
02783  oom:
02784
if
(!writer->type_pos_is_expectation)
02785     {
02786       new_bytes = _dbus_string_get_length (writer->type_str) - orig_type_len;
02787
group__DBusString.html#ga37
_dbus_string_delete
(writer->type_str, orig.
structDBusTypeWriter.html#o5
type_pos
, new_bytes);
02788     }
02789   new_bytes = _dbus_string_get_length (writer->value_str) - orig_value_len;
02790
group__DBusString.html#ga37
_dbus_string_delete
(writer->value_str, orig.
structDBusTypeWriter.html#o7
value_pos
, new_bytes);
02791
02792   *writer = orig;
02793
02794
return
group__DBusMacros.html#ga3
FALSE
;
02795 }
02796
02806
group__DBusTypes.html#ga2
dbus_bool_t
group__DBusMarshal.html#ga150
02807
group__DBusMarshal.html#ga150
_dbus_type_writer_write_reader
(
structDBusTypeWriter.html
DBusTypeWriter
*writer,
02808
structDBusTypeReader.html
DBusTypeReader
*reader)
02809 {
02810
return
group__DBusMarshal.html#ga149
_dbus_type_writer_write_reader_partial
(writer, reader, NULL, 0, 0, NULL);
02811 }
02812
02822
void
group__DBusMarshal.html#ga151
02823
group__DBusMarshal.html#ga151
_dbus_type_writer_set_enabled
(
structDBusTypeWriter.html
DBusTypeWriter
*writer,
02824
group__DBusTypes.html#ga2
dbus_bool_t
enabled)
02825 {
02826   writer->
structDBusTypeWriter.html#o3
enabled
= enabled !=
group__DBusMacros.html#ga3
FALSE
;
02827 }
02828
/* end of DBusMarshal group */
02830
02831
/* tests in dbus-marshal-recursive-util.c */
Generated on Tue Sep 13 01:28:07 2005 for D-BUS by
http://www.doxygen.org/index.html
doxygen
1.4.4
