import struct


def _read_entry(f, type):
    """Read a protobuf entry from a pirate log file.

    The pirate stores protobuf messages with the length prepended to
    the message as an uin32_t. This function first reads the uint32_t
    to determine the length of the entry and then the message
    itself. The message is then parsed using the appropriate protobuf
    class.

    Arguments:
       f - Input file.
       type - Protobuf entry type.

    Returns:
       Message object on success, None on orderly EOF.

    Exceptions:
       RuntimeError on EOF in the middle of a message.
    """

    # Read the entry length (uint32_t)
    packet_head = f.read(4)
    if len(packet_head) == 0:
        return None
    elif len(packet_head) != 4:
        raise RuntimeError('Unexpected EOF while reading packet length')

    (length, ) = struct.unpack("@I", packet_head)

    pb_message = type()
    packet = f.read(length)
    if len(packet) == 0:
        return None
    elif len(packet) != length:
        raise RuntimeError('Unexpected EOF while reading packet')

    pb_message.ParseFromString(packet)

    return pb_message