summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2013-06-23 20:12:56 +0200
committerAleksander Morgado <aleksander@lanedo.com>2013-06-24 19:22:32 +0200
commit491435b0ca78bf75ec726891c3ae6303dc265584 (patch)
treeeaf6a3f04ff15cda307caaaf64c1c259cf4bd6d5
parent580c0f25d86268768869c84634403210c9c08824 (diff)
downloadlibmbim-491435b0ca78bf75ec726891c3ae6303dc265584.tar.gz
mbim-codegen: handle reading/writing byte-arrays with shared length field
-rw-r--r--build-aux/mbim-codegen/Message.py6
-rw-r--r--build-aux/mbim-codegen/Struct.py55
-rw-r--r--libmbim-glib/mbim-message-private.h3
-rw-r--r--libmbim-glib/mbim-message.c111
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);
}