diff options
Diffstat (limited to 'dbus/dbus-marshal-recursive.c')
-rw-r--r-- | dbus/dbus-marshal-recursive.c | 174 |
1 files changed, 131 insertions, 43 deletions
diff --git a/dbus/dbus-marshal-recursive.c b/dbus/dbus-marshal-recursive.c index a8bad46a..2d4338ad 100644 --- a/dbus/dbus-marshal-recursive.c +++ b/dbus/dbus-marshal-recursive.c @@ -29,7 +29,11 @@ * @addtogroup DBusMarshal * @{ */ + +/** turn this on to get deluged in TypeReader verbose spam */ #define RECURSIVE_MARSHAL_READ_TRACE 0 + +/** turn this on to get deluged in TypeWriter verbose spam */ #define RECURSIVE_MARSHAL_WRITE_TRACE 0 static void @@ -101,18 +105,21 @@ apply_and_free_fixups (DBusList **fixups, *fixups = NULL; } +/** + * Virtual table for a type reader. + */ struct DBusTypeReaderClass { - const char *name; - int id; /* index in all_reader_classes */ - dbus_bool_t types_only; /* only iterates over types, not values */ + const char *name; /**< name for debugging */ + int id; /**< index in all_reader_classes */ + dbus_bool_t types_only; /**< only iterates over types, not values */ void (* recurse) (DBusTypeReader *sub, - DBusTypeReader *parent); - dbus_bool_t (* check_finished) (const DBusTypeReader *reader); + DBusTypeReader *parent); /**< recurse with this reader as sub */ + dbus_bool_t (* check_finished) (const DBusTypeReader *reader); /**< check whether reader is at the end */ void (* next) (DBusTypeReader *reader, - int current_type); + int current_type); /**< go to the next value */ void (* init_from_mark) (DBusTypeReader *reader, - const DBusTypeMark *mark); + const DBusTypeMark *mark); /**< uncompress from a mark */ }; static int @@ -201,7 +208,8 @@ array_types_only_reader_recurse (DBusTypeReader *sub, sub->array_len_offset = 7; } -/* array_len_offset is the offset back from start_pos to end of the len */ +/** compute position of array length given array_len_offset, which is + the offset back from start_pos to end of the len */ #define ARRAY_READER_LEN_POS(reader) \ ((reader)->u.array.start_pos - ((int)(reader)->array_len_offset) - 4) @@ -216,7 +224,7 @@ array_reader_get_array_len (const DBusTypeReader *reader) _dbus_assert (_DBUS_ALIGN_VALUE (len_pos, 4) == (unsigned) len_pos); array_len = _dbus_unpack_uint32 (reader->byte_order, _dbus_string_get_const_data_len (reader->value_str, len_pos, 4)); - + #if RECURSIVE_MARSHAL_READ_TRACE _dbus_verbose (" reader %p len_pos %d array len %u len_offset %d\n", reader, len_pos, array_len, reader->array_len_offset); @@ -315,27 +323,27 @@ skip_one_complete_type (const DBusString *type_str, { const unsigned char *p; const unsigned char *start; - + start = _dbus_string_get_const_data (type_str); p = start + *type_pos; while (*p == DBUS_TYPE_ARRAY) ++p; - + if (*p == DBUS_STRUCT_BEGIN_CHAR) { int depth; - + depth = 1; - + while (TRUE) { _dbus_assert (*p != DBUS_TYPE_INVALID); - + ++p; _dbus_assert (*p != DBUS_TYPE_INVALID); - + if (*p == DBUS_STRUCT_BEGIN_CHAR) depth += 1; else if (*p == DBUS_STRUCT_END_CHAR) @@ -632,6 +640,16 @@ all_reader_classes[] = { &variant_reader_class }; +/** + * Initializes a type reader. + * + * @param reader the reader + * @param byte_order the byte order of the block to read + * @param type_str the signature of the block to read + * @param type_pos location of signature + * @param value_str the string containing values block + * @param value_pos start of values block + */ void _dbus_type_reader_init (DBusTypeReader *reader, int byte_order, @@ -652,6 +670,17 @@ _dbus_type_reader_init (DBusTypeReader *reader, #endif } +/** + * Initializes a type reader that's been compressed into a + * DBusTypeMark. The args have to be the same as those passed in to + * create the original #DBusTypeReader. + * + * @param reader the reader + * @param byte_order the byte order of the value block + * @param type_str string containing the type signature + * @param value_str string containing the values block + * @param mark the mark to decompress from + */ void _dbus_type_reader_init_from_mark (DBusTypeReader *reader, int byte_order, @@ -676,6 +705,14 @@ _dbus_type_reader_init_from_mark (DBusTypeReader *reader, #endif } +/** + * Like _dbus_type_reader_init() but the iteration is over the + * signature, not over values. + * + * @param reader the reader + * @param type_str the signature string + * @param type_pos location in the signature string + */ void _dbus_type_reader_init_types_only (DBusTypeReader *reader, const DBusString *type_str, @@ -693,6 +730,14 @@ _dbus_type_reader_init_types_only (DBusTypeReader *reader, #endif } +/** + * Like _dbus_type_reader_init_from_mark() but only iterates over + * the signature, not the values. + * + * @param reader the reader + * @param type_str the signature string + * @param mark the mark to decompress from + */ void _dbus_type_reader_init_types_only_from_mark (DBusTypeReader *reader, const DBusString *type_str, @@ -716,6 +761,13 @@ _dbus_type_reader_init_types_only_from_mark (DBusTypeReader *reader, #endif } +/** + * Compresses a type reader into a #DBusTypeMark, useful for example + * if you want to cache a bunch of positions in a block of values. + * + * @param reader the reader + * @param mark the mark to init + */ void _dbus_type_reader_save_mark (const DBusTypeReader *reader, DBusTypeMark *mark) @@ -732,6 +784,14 @@ _dbus_type_reader_save_mark (const DBusTypeReader *reader, mark->array_start_pos = reader->u.array.start_pos; } +/** + * Gets the type of the value the reader is currently pointing to; + * or for a types-only reader gets the type it's currently pointing to. + * If the reader is at the end of a block or end of a container such + * as an array, returns #DBUS_TYPE_INVALID. + * + * @param reader the reader + */ int _dbus_type_reader_get_current_type (const DBusTypeReader *reader) { @@ -757,8 +817,16 @@ _dbus_type_reader_get_current_type (const DBusTypeReader *reader) return t; } +/** + * Gets the type of an element of the array the reader is currently + * pointing to. It's an error to call this if + * _dbus_type_reader_get_current_type() doesn't return #DBUS_TYPE_ARRAY + * for this reader. + * + * @param reader the reader + */ int -_dbus_type_reader_get_array_type (const DBusTypeReader *reader) +_dbus_type_reader_get_element_type (const DBusTypeReader *reader) { int element_type; @@ -770,36 +838,25 @@ _dbus_type_reader_get_array_type (const DBusTypeReader *reader) return element_type; } +/** + * Gets the current position in the value block + * @param reader the reader + */ int _dbus_type_reader_get_value_pos (const DBusTypeReader *reader) { return reader->value_pos; } -dbus_bool_t +/** + * Checks whether an array has any elements. + * + * @param reader the reader + */ +static dbus_bool_t _dbus_type_reader_array_is_empty (const DBusTypeReader *reader) { - dbus_uint32_t array_len; - - _dbus_assert (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_ARRAY); - _dbus_assert (!reader->klass->types_only); - - /* reader is supposed to be at an array child */ -#if RECURSIVE_MARSHAL_READ_TRACE - _dbus_verbose ("checking array len at %d\n", reader->value_pos); -#endif - - _dbus_marshal_read_basic (reader->value_str, - reader->value_pos, - DBUS_TYPE_UINT32, - &array_len, - reader->byte_order, - NULL); -#if RECURSIVE_MARSHAL_READ_TRACE - _dbus_verbose (" ... array len = %d\n", array_len); -#endif - - return array_len == 0; + return array_reader_get_array_len (reader) == 0; } /** @@ -822,6 +879,12 @@ _dbus_type_reader_read_raw (const DBusTypeReader *reader, 0); } +/** + * Reads a basic-typed value, as with _dbus_marshal_read_basic(). + * + * @param reader the reader + * @param value the address of the value + */ void _dbus_type_reader_read_basic (const DBusTypeReader *reader, void *value) @@ -1852,7 +1915,7 @@ writer_recurse_array (DBusTypeWriter *writer, _dbus_string_get_const_data_len (sub->value_str, sub->u.array.len_pos, 4)); - + sub->value_pos += len; } } @@ -2006,6 +2069,16 @@ _dbus_type_writer_recurse_contained_len (DBusTypeWriter *writer, } } +/** + * Opens a new container and writes out the initial information for that container. + * + * @param writer the writer + * @param container_type the type of the container to open + * @param contained_type the array element type or variant content type + * @param contained_type_start position to look for the type + * @param sub the new sub-writer to write container contents + * @returns #FALSE if no memory + */ dbus_bool_t _dbus_type_writer_recurse (DBusTypeWriter *writer, int container_type, @@ -2068,6 +2141,14 @@ writer_get_array_len (DBusTypeWriter *writer) return writer->value_pos - writer->u.array.start_pos; } +/** + * Closes a container created by _dbus_type_writer_recurse() + * and writes any additional information to the values block. + * + * @param writer the writer + * @param sub the sub-writer created by _dbus_type_writer_recurse() + * @returns #FALSE if no memory + */ dbus_bool_t _dbus_type_writer_unrecurse (DBusTypeWriter *writer, DBusTypeWriter *sub) @@ -2182,6 +2263,14 @@ _dbus_type_writer_unrecurse (DBusTypeWriter *writer, return TRUE; } +/** + * Writes out a basic type. + * + * @param writer the writer + * @param type the type to write + * @param value the address of the value to write + * @returns #FALSE if no memory + */ dbus_bool_t _dbus_type_writer_write_basic (DBusTypeWriter *writer, int type, @@ -2452,7 +2541,7 @@ writer_write_reader_helper (DBusTypeWriter *writer, _dbus_assert (_DBUS_ALIGN_VALUE (fixup.len_pos_in_reader, 4) == (unsigned) fixup.len_pos_in_reader); - + old_len = _dbus_unpack_uint32 (reader->byte_order, _dbus_string_get_const_data_len (reader->value_str, fixup.len_pos_in_reader, 4)); @@ -3515,7 +3604,6 @@ typedef struct int n_nodes; } NodeIterationData; - static dbus_bool_t run_test_copy (NodeIterationData *nid) { @@ -5345,7 +5433,7 @@ array_read_or_set_value (TestTypeNode *node, _dbus_type_reader_recurse (reader, &sub); if (realign_root == NULL && arrays_write_fixed_in_blocks && - _dbus_type_is_fixed (_dbus_type_reader_get_array_type (reader)) && + _dbus_type_is_fixed (_dbus_type_reader_get_element_type (reader)) && child->klass->read_multi) { if (!node_read_multi (child, &sub, seed, n_copies)) @@ -5365,7 +5453,7 @@ array_read_or_set_value (TestTypeNode *node, DBusList *next = _dbus_list_get_next_link (&container->children, link); _dbus_assert (child->klass->typecode == - _dbus_type_reader_get_array_type (reader)); + _dbus_type_reader_get_element_type (reader)); if (realign_root == NULL) { |