import struct


def read_message(in_file, msg_class):
  """Reads the given proto Message subclass from the file descriptor `in_file`.

  This expects a 4-byte network-order (big-endian) size prefix, followed by
  exactly that many bytes, which should be the binary encoded form of a
  `msg_class` message.

  Args:

    * in_file (file-like object) - The handle to read the size header and proto.
    * msg_class (google.protobuf.Message subclass) - The generated proto Message
      to decode from the stream.

  Returns None (on EOF/partial read) or an instance of msg_class.
  Raises any error that msg_class.ParseFromString could raise.
  """
  raw_size = in_file.read(4)
  if raw_size is None or len(raw_size) != 4:
    return None

  size, = struct.unpack('!L', raw_size)
  data = in_file.read(size)
  if data is None or len(data) != size:
    return None

  ret = msg_class()
  ret.ParseFromString(data)
  return ret