'Provides the bulk of the internal implementation for readfrom and
fromstring.
For some special cases, supports using a header that was already
created, and just using the input data for the actual array data.'

@classmethod
def _readfrom_internal(cls, data, header=None, checksum=False, ignore_missing_end=False, **kwargs):

    hdu_buffer = None
    hdu_fileobj = None
    header_offset = 0
    if isinstance(data, _File):
        if (header is None):
            header_offset = data.tell()
            header = Header.fromfile(data, endcard=(not ignore_missing_end))
        hdu_fileobj = data
        data_offset = data.tell()
    else:
        try:
            np.ndarray((), dtype='ubyte', buffer=data)
        except TypeError:
            raise TypeError('The    provided    object    {!r}    does    not    contain    an    underlying    memory    buffer.        fromstring()    requires    an    object    that    supports    the    buffer    interface    such    as    bytes,    str    (in    Python    2.x    but    not    in    3.x),    buffer,    memoryview,    ndarray,    etc.        This    restriction    is    to    ensure    that    efficient    access    to    the    array/table    data    is    possible.'.format(data))
        if (header is None):
            def block_iter(nbytes):
                idx = 0
                while (idx < len(data)):
                    (yield data[idx:(idx + nbytes)])
                    idx += nbytes
            (header_str, header) = Header._from_blocks(block_iter, True, '', (not ignore_missing_end), True)
            if (len(data) > len(header_str)):
                hdu_buffer = data
        elif data:
            hdu_buffer = data
        header_offset = 0
        data_offset = len(header_str)
    cls = _hdu_class_from_header(cls, header)
    sig = signature(cls.__init__)
    new_kwargs = kwargs.copy()
    if (Parameter.VAR_KEYWORD not in (x.kind for x in sig.parameters.values())):
        for key in kwargs:
            if (key not in sig.parameters):
                del new_kwargs[key]
    hdu = cls(data=DELAYED, header=header, **new_kwargs)
    hdu._file = hdu_fileobj
    hdu._buffer = hdu_buffer
    hdu._header_offset = header_offset
    hdu._data_offset = data_offset
    size = hdu.size
    hdu._data_size = (size + _pad_length(size))
    if (checksum and (checksum != 'remove') and isinstance(hdu, _ValidHDU)):
        hdu._verify_checksum_datasum(checksum)
    return hdu
