import struct


def read_tfrecord(input):
    """ Read a binary TFRecord from the given input stream, and return the raw
    bytes. """

    # Each TFRecord has the following format, we will only read the first 8
    # bytes in order to fetch the `length`, and then assume the rest of the
    # record looks correct.
    #
    # ```
    # uint64 length
    # uint32 masked_crc32_of_length
    # byte   data[length]
    # uint32 masked_crc32_of_data
    # ```
    #
    length_bytes = b''

    while len(length_bytes) < 8:
        buf = input.read(8 - len(length_bytes))
        if not buf:
            return None

        length_bytes += buf

    length = struct.unpack('<Q', length_bytes)[0] + 8
    remaining = b''

    while len(remaining) < length:
        remaining += input.read(length - len(remaining))

    return length_bytes + remaining