(encoding, *, base)
return structish_type
Create a structish type from the given encoding. ("structish" = "structure or union")
    The base kwarg controls which base class is used. It should be either ctypes.Structure or ctypes.Union.
Create a structish type from the given encoding. ("structish" = "structure or union")
    The base kwarg controls which base class is used. It should be either ctypes.Structure or ctypes.Union.
Create a structish type from the given encoding . ( structish = structure or union ) The base kwarg controls which base class is used . It should be either ctypes . Structure or ctypes . Union .
def _create_structish_type_for_encoding(encoding, *, base):
    """Create a structish type from the given encoding. ("structish" = "structure or union")
    The base kwarg controls which base class is used. It should be either ctypes.Structure or ctypes.Union.
    """

    # Split name and fields.
    begin = encoding[0:1]
    end = encoding[-1:len(encoding)]
    name, eq, fields = encoding[1:-1].partition(b'=')

    if not eq:
        # If the fields are not present, we can't create a meaningful structish.
        # We also know that there is no known structish with this name,
        # because in that case that structish would have been found by ctype_for_encoding.
        # So we pretend that this structish is a void (None).
        # This causes pointers to it to become void pointers.
        return None

    if name == b'?':
        # Anonymous structish, has no name.
        name = None

    # Create the subclass. The _fields_ are not set yet, this is done later.
    # The structish is already registered here, so that pointers to this structish type in itself are typed correctly.
    py_name = '_Anonymous' if name is None else name.decode('utf-8')
    structish_type = type(py_name, (base,), {})
    # Register the structish for its own encoding, so the same type is used in the future.
    register_encoding(encoding, structish_type)
    if name is not None:
        # If not anonymous, also register for the corresponding name-only encoding.
        register_encoding(begin + name + end, structish_type)

    # Convert the field encodings to a sequence of tuples, as needed for the _fields_ attribute.
    ctypes_fields = []
    start = 0  # Start of the next field.
    i = 0  # Field counter, used when naming unnamed fields.
    while start < len(fields):
        if fields[start:start+1] == b'"':
            # If a name is present, use it.
            field_name_end = fields.index(b'"', start+2)
            field_name = fields[start+1:field_name_end].decode('utf-8')
            start = field_name_end+1
        else:
            # If no name is present, make one based on the field index.
            field_name = 'field_{}'.format(i)
        end = _end_of_encoding(fields, start)
        field_encoding = fields[start:end]
        if field_encoding.startswith(b'b'):
            # Bit field, extract the number of bits.
            bit_field_size = int(field_encoding[1:])
            ctypes_fields.append((field_name, c_uint, bit_field_size))
        else:
            # Regular field, decode the encoding normally.
            field_type = ctype_for_encoding(field_encoding)
            ctypes_fields.append((field_name, field_type))
        start = end
        i += 1

    structish_type._fields_ = ctypes_fields

    return structish_type
def _create_structish_type_for_encoding ( encoding , * , base ) : # Split name and fields. begin = encoding [ 0 : 1 ] end = encoding [ - 1 : len ( encoding ) ] name , eq , fields = encoding [ 1 : - 1 ] . partition ( b'=' ) if not eq : # If the fields are not present, we can't create a meaningful structish. # We also know that there is no known structish with this name, # because in that case that structish would have been found by ctype_for_encoding. # So we pretend that this structish is a void (None). # This causes pointers to it to become void pointers. return None if name == b'?' : # Anonymous structish, has no name. name = None # Create the subclass. The _fields_ are not set yet, this is done later. # The structish is already registered here, so that pointers to this structish type in itself are typed correctly. py_name = '_Anonymous' if name is None else name . decode ( 'utf-8' ) structish_type = type ( py_name , ( base , ) , { } ) # Register the structish for its own encoding, so the same type is used in the future. register_encoding ( encoding , structish_type ) if name is not None : # If not anonymous, also register for the corresponding name-only encoding. register_encoding ( begin + name + end , structish_type ) # Convert the field encodings to a sequence of tuples, as needed for the _fields_ attribute. ctypes_fields = [ ] start = 0 # Start of the next field. i = 0 # Field counter, used when naming unnamed fields. while start < len ( fields ) : if fields [ start : start + 1 ] == b'"' : # If a name is present, use it. field_name_end = fields . index ( b'"' , start + 2 ) field_name = fields [ start + 1 : field_name_end ] . decode ( 'utf-8' ) start = field_name_end + 1 else : # If no name is present, make one based on the field index. field_name = 'field_{}' . format ( i ) end = _end_of_encoding ( fields , start ) field_encoding = fields [ start : end ] if field_encoding . startswith ( b'b' ) : # Bit field, extract the number of bits. bit_field_size = int ( field_encoding [ 1 : ] ) ctypes_fields . append ( ( field_name , c_uint , bit_field_size ) ) else : # Regular field, decode the encoding normally. field_type = ctype_for_encoding ( field_encoding ) ctypes_fields . append ( ( field_name , field_type ) ) start = end i += 1 structish_type . _fields_ = ctypes_fields return structish_type