<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def read_struct_file(struct_data):
 """Interpret a struct file defining the location of variables in memory. Parameters struct_data : :py:class:`bytes` String of :py:class:`bytes` containing data to interpret as the struct definition. Returns ------- {struct_name: :py:class:`~.Struct`} A dictionary mapping the struct name to a :py:class:`~.Struct` instance. **Note:** the struct name will be a string of bytes, e.g., `b"vcpu"`. """

    # Holders for all structs
    structs = dict()

    # Holders for the current struct
    name = None

    # Iterate over every line in the file
    for i, l in enumerate(struct_data.splitlines()):
        # Empty the line of comments, if the line is empty then skip to the
        # next line.  Split on whitespace to get the tokens.
        tokens = re_comment.sub(b"", l).strip().split()
        if len(tokens) == 0:
            continue
        elif len(tokens) == 3:
            # 3 tokens implies header data
            (key, _, value) = tokens

            if key == b"name":
                if name is not None:
                    if structs[name].size is None:
                        raise ValueError(
                            "size value missing for struct '{}'".format(name))
                    if structs[name].base is None:
                        raise ValueError(
                            "base value missing for struct '{}'".format(name))
                name = value
                structs[name] = Struct(name)
            elif key == b"size":
                structs[name].size = num(value)
            elif key == b"base":
                structs[name].base = num(value)
            else:
                raise ValueError(key)
        elif len(tokens) == 5:
            # 5 tokens implies entry in struct.
            (field, pack, offset, printf, default) = tokens

            # Convert the packing character from Perl to Python standard
            num_pack = re_numbered_pack.match(pack)
            if num_pack is not None:
                pack = (num_pack.group("num") +
                        perl_to_python_packs[num_pack.group("char")])
            else:
                pack = perl_to_python_packs[pack]

            # If the field is an array then extract the length
            length = 1
            field_exp = re_array_field.match(field)
            if field_exp is not None:
                field = field_exp.group("field")
                length = num(field_exp.group("length"))

            structs[name][field] = StructField(pack, num(offset), printf,
                                               num(default), length)
        else:
            raise ValueError(
                "line {}: Invalid syntax in struct file".format(i))

    # Final check for setting size and base
    if structs[name].size is None:
        raise ValueError(
            "size value missing for struct '{}'".format(name))
    if structs[name].base is None:
        raise ValueError(
            "base value missing for struct '{}'".format(name))

    return structs