code: def decode_utf8(f):
      
      decode = codecs.getdecoder('utf8')
  
      buf = f.read(FIELD_U16.size)
      if len(buf) < FIELD_U16.size:
          raise UnderflowDecodeError()
  
      (num_utf8_bytes,) = FIELD_U16.unpack_from(buf)
      num_bytes_consumed = FIELD_U16.size + num_utf8_bytes
  
      buf = f.read(num_utf8_bytes)
      if len(buf) < num_utf8_bytes:
          raise UnderflowDecodeError()
  
      try:
          s, num_chars = decode(buf, 'strict')
      except UnicodeError as e:
          raise Utf8DecodeError(e)
  
      return num_bytes_consumed, s
docs: Decode a utf-8 string encoded as described in MQTT Version
      3.1.1 section 1.5.3 line 177.  This is a 16-bit unsigned length
      followed by a utf-8 encoded string.
  
      Parameters
      ----------
      f: file
          File-like object with read method.
  
      Raises
      ------
      UnderflowDecodeError
          Raised when a read failed to extract enough bytes from the
          underlying stream to decode the string.
      Utf8DecodeError
          When any code point in the utf-8 string is invalid.
  
      Returns
      -------
      int
          Number of bytes consumed.
      str
          A string utf-8 decoded from ``f``.