+ return offset;
+}
+
+/* Checks whether we have more items in the array to iterate, or more arrays to
+ * iterate through.
+ */
+/* descend into a non-array field */
+static void
+iter_push_array(struct gen_field_iterator *iter)
+{
+ assert(iter->level >= 0);
+
+ iter->group = iter->field->array;
+ iter->level++;
+ assert(iter->level < DECODE_MAX_ARRAY_DEPTH);
+ iter->groups[iter->level] = iter->group;
+ iter->array_iter[iter->level] = 0;
+
+ assert(iter->group->fields != NULL); /* an empty <group> makes no sense */
+ iter->field = iter->group->fields;
+ iter->fields[iter->level] = iter->field;
+}
+
+static void
+iter_pop_array(struct gen_field_iterator *iter)
+{
+ assert(iter->level > 0);
+
+ iter->level--;
+ iter->field = iter->fields[iter->level];
+ iter->group = iter->groups[iter->level];
+}
+
+static void
+iter_start_field(struct gen_field_iterator *iter, struct gen_field *field)
+{
+ iter->field = field;
+ iter->fields[iter->level] = field;
+
+ while (iter->field->array)
+ iter_push_array(iter);
+
+ int array_member_offset = iter_array_offset_bits(iter);
+
+ iter->start_bit = array_member_offset + iter->field->start;
+ iter->end_bit = array_member_offset + iter->field->end;
+ iter->struct_desc = NULL;
+}
+
+static void
+iter_advance_array(struct gen_field_iterator *iter)
+{
+ assert(iter->level > 0);
+ int lvl = iter->level;
+
+ if (iter->group->variable)
+ iter->array_iter[lvl]++;
+ else {
+ if ((iter->array_iter[lvl] + 1) < iter->group->array_count) {
+ iter->array_iter[lvl]++;
+ }
+ }
+
+ iter_start_field(iter, iter->group->fields);
+}
+
+static bool
+iter_more_array_elems(const struct gen_field_iterator *iter)
+{
+ int lvl = iter->level;
+ assert(lvl >= 0);
+
+ if (iter->group->variable) {
+ int length = gen_group_get_length(iter->group, iter->p);
+ assert(length >= 0 && "error the length is unknown!");
+ return iter_array_offset_bits(iter) + iter->group->array_item_size <
+ (length * 32);
+ } else {
+ return (iter->array_iter[lvl] + 1) < iter->group->array_count;
+ }
+}