diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2013-06-23 20:12:56 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2013-06-24 19:22:32 +0200 |
commit | 491435b0ca78bf75ec726891c3ae6303dc265584 (patch) | |
tree | eaf6a3f04ff15cda307caaaf64c1c259cf4bd6d5 | |
parent | 580c0f25d86268768869c84634403210c9c08824 (diff) | |
download | libmbim-491435b0ca78bf75ec726891c3ae6303dc265584.tar.gz |
mbim-codegen: handle reading/writing byte-arrays with shared length field
-rw-r--r-- | build-aux/mbim-codegen/Message.py | 6 | ||||
-rw-r--r-- | build-aux/mbim-codegen/Struct.py | 55 | ||||
-rw-r--r-- | libmbim-glib/mbim-message-private.h | 3 | ||||
-rw-r--r-- | libmbim-glib/mbim-message.c | 111 |
4 files changed, 126 insertions, 49 deletions
diff --git a/build-aux/mbim-codegen/Message.py b/build-aux/mbim-codegen/Message.py index fc5da03..cbeb239 100644 --- a/build-aux/mbim-codegen/Message.py +++ b/build-aux/mbim-codegen/Message.py @@ -722,7 +722,7 @@ class Message: inner_template += ( ' const guint8 *tmp;\n' '\n' - ' tmp = _mbim_message_read_byte_array (message, 0, offset, FALSE, NULL);\n' + ' tmp = _mbim_message_read_byte_array (message, 0, offset, FALSE, FALSE, NULL);\n' ' if (${field} != NULL)\n' ' *${field} = tmp;\n' ' offset += ${array_size};\n') @@ -731,7 +731,7 @@ class Message: ' const guint8 *tmp;\n' ' guint32 tmpsize;\n' '\n' - ' tmp = _mbim_message_read_byte_array (message, 0, offset, FALSE, &tmpsize);\n' + ' tmp = _mbim_message_read_byte_array (message, 0, offset, FALSE, FALSE, &tmpsize);\n' ' if (${field} != NULL)\n' ' *${field} = tmp;\n' ' if (${field}_size != NULL)\n' @@ -742,7 +742,7 @@ class Message: ' const guint8 *tmp;\n' ' guint32 tmpsize;\n' '\n' - ' tmp = _mbim_message_read_byte_array (message, 0, offset, TRUE, &tmpsize);\n' + ' tmp = _mbim_message_read_byte_array (message, 0, offset, TRUE, TRUE, &tmpsize);\n' ' if (${field} != NULL)\n' ' *${field} = tmp;\n' ' if (${field}_size != NULL)\n' diff --git a/build-aux/mbim-codegen/Struct.py b/build-aux/mbim-codegen/Struct.py index 5983cc1..afe2ba5 100644 --- a/build-aux/mbim-codegen/Struct.py +++ b/build-aux/mbim-codegen/Struct.py @@ -74,8 +74,10 @@ class Struct: elif field['format'] =='byte-array': inner_template = (' * @${field_name_underscore}: an array of #guint8 values.\n') elif field['format'] =='unsized-byte-array' or field['format'] == 'ref-byte-array': - inner_template = (' * @${field_name_underscore}_size: size of the ${field_name_underscore} array.\n' - ' * @${field_name_underscore}: an array of #guint8 values.\n') + inner_template = '' + if 'array-size-field' not in field: + inner_template += (' * @${field_name_underscore}_size: size of the ${field_name_underscore} array.\n') + inner_template += (' * @${field_name_underscore}: an array of #guint8 values.\n') elif field['format'] == 'guint32': inner_template = ( ' * @${field_name_underscore}: a #guint32.\n') @@ -126,8 +128,11 @@ class Struct: inner_template = ( ' guint8 ${field_name_underscore}[${array_size}];\n') elif field['format'] == 'unsized-byte-array' or field['format'] == 'ref-byte-array': - inner_template = ( - ' guint32 ${field_name_underscore}_size;\n' + inner_template = '' + if 'array-size-field' not in field: + inner_template += ( + ' guint32 ${field_name_underscore}_size;\n') + inner_template += ( ' guint8 *${field_name_underscore};\n') elif field['format'] == 'guint32': inner_template = ( @@ -316,23 +321,36 @@ class Struct: ' memcpy (&(out->${field_name_underscore}), _mbim_message_read_uuid (self, offset), 16);\n' ' offset += 16;\n') elif field['format'] == 'ref-byte-array': - inner_template += ( - '\n' - ' {\n' - ' const guint8 *tmp;\n' - '\n' - ' tmp = _mbim_message_read_byte_array (self, relative_offset, offset, TRUE, &(out->${field_name_underscore}_size));\n' - ' out->${field_name_underscore} = g_malloc (out->${field_name_underscore}_size);\n' - ' memcpy (out->${field_name_underscore}, tmp, out->${field_name_underscore}_size);\n' - ' offset += 8;\n' - ' }\n') + if 'array-size-field' in field: + translations['array_size_field_name_underscore'] = utils.build_underscore_name_from_camelcase(field['array-size-field']) + inner_template += ( + '\n' + ' {\n' + ' const guint8 *tmp;\n' + '\n' + ' tmp = _mbim_message_read_byte_array (self, relative_offset, offset, TRUE, FALSE, NULL);\n' + ' out->${field_name_underscore} = g_malloc (out->${array_size_field_name_underscore});\n' + ' memcpy (out->${field_name_underscore}, tmp, out->${array_size_field_name_underscore});\n' + ' offset += 4;\n' + ' }\n') + else: + inner_template += ( + '\n' + ' {\n' + ' const guint8 *tmp;\n' + '\n' + ' tmp = _mbim_message_read_byte_array (self, relative_offset, offset, TRUE, TRUE, &(out->${field_name_underscore}_size));\n' + ' out->${field_name_underscore} = g_malloc (out->${field_name_underscore}_size);\n' + ' memcpy (out->${field_name_underscore}, tmp, out->${field_name_underscore}_size);\n' + ' offset += 8;\n' + ' }\n') elif field['format'] == 'unsized-byte-array': inner_template += ( '\n' ' {\n' ' const guint8 *tmp;\n' '\n' - ' tmp = _mbim_message_read_byte_array (self, relative_offset, offset, FALSE, &(out->${field_name_underscore}_size));\n' + ' tmp = _mbim_message_read_byte_array (self, relative_offset, offset, FALSE, FALSE, &(out->${field_name_underscore}_size));\n' ' out->${field_name_underscore} = g_malloc (out->${field_name_underscore}_size);\n' ' memcpy (out->${field_name_underscore}, tmp, out->${field_name_underscore}_size);\n' ' /* no offset update expected, this should be the last field */\n' @@ -344,7 +362,7 @@ class Struct: ' {\n' ' const guint8 *tmp;\n' '\n' - ' tmp = _mbim_message_read_byte_array (self, relative_offset, offset, FALSE, NULL));\n' + ' tmp = _mbim_message_read_byte_array (self, relative_offset, offset, FALSE, FALSE, NULL));\n' ' memcpy (out->${field_name_underscore}, tmp, ${array_size});\n' ' offset += ${array_size};\n' ' }\n') @@ -484,7 +502,10 @@ class Struct: elif field['format'] == 'unsized-byte-array': inner_template = (' _mbim_struct_builder_append_byte_array (builder, FALSE, FALSE, value->${field}, value->${field}_size);\n') elif field['format'] == 'ref-byte-array': - inner_template = (' _mbim_struct_builder_append_byte_array (builder, TRUE, TRUE, value->${field}, value->${field}_size);\n') + if 'array-size-field' in field: + inner_template = (' _mbim_struct_builder_append_byte_array (builder, TRUE, FALSE, value->${field}, value->${array_size_field});\n') + else: + inner_template = (' _mbim_struct_builder_append_byte_array (builder, TRUE, TRUE, value->${field}, value->${field}_size);\n') elif field['format'] == 'guint32': inner_template = (' _mbim_struct_builder_append_guint32 (builder, value->${field});\n') elif field['format'] == 'guint32-array': diff --git a/libmbim-glib/mbim-message-private.h b/libmbim-glib/mbim-message-private.h index 4de66ec..5d9d509 100644 --- a/libmbim-glib/mbim-message-private.h +++ b/libmbim-glib/mbim-message-private.h @@ -259,7 +259,8 @@ void _mbim_message_command_builder_append_ipv6_array (M const guint8 *_mbim_message_read_byte_array (const MbimMessage *self, guint32 struct_start_offset, guint32 relative_offset, - gboolean ol_pair, + gboolean has_offset, + gboolean has_length, guint32 *array_size); const MbimUuid *_mbim_message_read_uuid (const MbimMessage *self, guint32 relative_offset); diff --git a/libmbim-glib/mbim-message.c b/libmbim-glib/mbim-message.c index 0fe0e84..97f15d4 100644 --- a/libmbim-glib/mbim-message.c +++ b/libmbim-glib/mbim-message.c @@ -231,42 +231,82 @@ _mbim_message_read_string_array (const MbimMessage *self, return array; } +/* + * Byte arrays may be given in very different ways: + * - (a) Offset + Length pair in static buffer, data in variable buffer. + * - (b) Just length in static buffer, data just afterwards. + * - (c) Just offset in static buffer, length given in another variable, data in variable buffer. + * - (d) Fixed-sized array directly in the static buffer. + * - (e) Unsized array directly in the variable buffer, length is assumed until end of message. + */ const guint8 * _mbim_message_read_byte_array (const MbimMessage *self, guint32 struct_start_offset, guint32 relative_offset, - gboolean ol_pair, + gboolean has_offset, + gboolean has_length, guint32 *array_size) { guint32 information_buffer_offset; - guint32 size; - guint32 offset; - const guint8 *data; information_buffer_offset = _mbim_message_get_information_buffer_offset (self); - if (ol_pair) { + /* (a) Offset + Length pair in static buffer, data in variable buffer. */ + if (has_offset && has_length) { + guint32 offset; + + g_assert (array_size != NULL); + offset = GUINT32_FROM_LE (G_STRUCT_MEMBER ( guint32, self->data, (information_buffer_offset + relative_offset))); - size = GUINT32_FROM_LE (G_STRUCT_MEMBER ( - guint32, - self->data, - (information_buffer_offset + relative_offset + 4))); - data = (const guint8 *) G_STRUCT_MEMBER_P (self->data, + *array_size = GUINT32_FROM_LE (G_STRUCT_MEMBER ( + guint32, + self->data, + (information_buffer_offset + relative_offset + 4))); + return (const guint8 *) G_STRUCT_MEMBER_P (self->data, (information_buffer_offset + struct_start_offset + offset)); - } else { - size = self->len - (information_buffer_offset + relative_offset); - data = (const guint8 *) G_STRUCT_MEMBER_P (self->data, - (information_buffer_offset + relative_offset)); } - /* We assume that the byte array goes until the end */ - if (array_size) - *array_size = size; + /* (b) Just length in static buffer, data just afterwards. */ + if (!has_offset && has_length) { + g_assert (array_size != NULL); - return data; + *array_size = GUINT32_FROM_LE (G_STRUCT_MEMBER ( + guint32, + self->data, + (information_buffer_offset + relative_offset))); + return (const guint8 *) G_STRUCT_MEMBER_P (self->data, + (information_buffer_offset + relative_offset + 4)); + } + + /* (c) Just offset in static buffer, length given in another variable, data in variable buffer. */ + if (has_offset && !has_length) { + guint32 offset; + + g_assert (array_size == NULL); + + offset = GUINT32_FROM_LE (G_STRUCT_MEMBER ( + guint32, + self->data, + (information_buffer_offset + relative_offset))); + return (const guint8 *) G_STRUCT_MEMBER_P (self->data, + (information_buffer_offset + struct_start_offset + offset)); + } + + /* (d) Fixed-sized array directly in the static buffer. + * (e) Unsized array directly in the variable buffer, length is assumed until end of message. */ + if (!has_offset && !has_length) { + /* If array size is requested, it's case (e) */ + if (array_size) + *array_size = self->len - (information_buffer_offset + relative_offset); + + return (const guint8 *) G_STRUCT_MEMBER_P (self->data, + (information_buffer_offset + relative_offset)); + } + + g_assert_not_reached (); } const MbimUuid * @@ -440,6 +480,14 @@ _mbim_struct_builder_complete (MbimStructBuilder *builder) return out; } +/* + * Byte arrays may be given in very different ways: + * - (a) Offset + Length pair in static buffer, data in variable buffer. + * - (b) Just length in static buffer, data just afterwards. + * - (c) Just offset in static buffer, length given in another variable, data in variable buffer. + * - (d) Fixed-sized array directly in the static buffer. + * - (e) Unsized array directly in the variable buffer, length is assumed until end of message. + */ void _mbim_struct_builder_append_byte_array (MbimStructBuilder *builder, gboolean with_offset, @@ -447,18 +495,22 @@ _mbim_struct_builder_append_byte_array (MbimStructBuilder *builder, const guint8 *buffer, guint32 buffer_len) { - guint32 offset; - guint32 length; - + /* + * (d) Fixed-sized array directly in the static buffer. + * (e) Unsized array directly in the variable buffer (here end of static buffer is also beginning of variable) + */ if (!with_offset && !with_length) { g_byte_array_append (builder->fixed_buffer, buffer, buffer_len); return; } - /* A bytearray consists of Offset+Size in the static buffer, plus the - * string itself in the variable buffer */ + /* (a) Offset + Length pair in static buffer, data in variable buffer. + * This case is the sum of cases b+c */ + /* (c) Just offset in static buffer, length given in another variable, data in variable buffer. */ if (with_offset) { + guint32 offset; + /* If string length is greater than 0, add the offset to fix, otherwise set * the offset to 0 and don't configure the update */ if (buffer_len == 0) { @@ -479,14 +531,17 @@ _mbim_struct_builder_append_byte_array (MbimStructBuilder *builder, } } - g_assert (with_length == TRUE); + /* (b) Just length in static buffer, data just afterwards. */ + if (with_length) { + guint32 length; - /* Add the length value */ - length = GUINT32_TO_LE (buffer_len); - g_byte_array_append (builder->fixed_buffer, (guint8 *)&length, sizeof (length)); + /* Add the length value */ + length = GUINT32_TO_LE (buffer_len); + g_byte_array_append (builder->fixed_buffer, (guint8 *)&length, sizeof (length)); + } /* And finally, the bytearray itself to the variable buffer */ - if (length) + if (buffer_len) g_byte_array_append (builder->variable_buffer, (const guint8 *)buffer, (guint)buffer_len); } |