docs: def parse_packets(stream):
      """
      Support iterative parsing of available GPG packets.
  
      See https://tools.ietf.org/html/rfc4880#section-4.2 for details.
      """
      reader = util.Reader(stream)
      while True:
          try:
              value = reader.readfmt('B')
          except EOFError:
              return
  
          log.debug('prefix byte: %s', bin(value))
          assert util.bit(value, 7) == 1
  
          tag = util.low_bits(value, 6)
          if util.bit(value, 6) == 0:
              length_type = util.low_bits(tag, 2)
              tag = tag >> 2
              fmt = {0: '>B', 1: '>H', 2: '>L'}[length_type]
              packet_size = reader.readfmt(fmt)
          else:
              first = reader.readfmt('B')
              if first < 192:
                  packet_size = first
              elif first < 224:
                  packet_size = ((first - 192) << 8) + reader.readfmt('B') + 192
              elif first == 255:
                  packet_size = reader.readfmt('>L')
              else:
                  log.error('Partial Body Lengths unsupported')
  
          log.debug('packet length: %d', packet_size)
          packet_data = reader.read(packet_size)
          packet_type = PACKET_TYPES.get(tag)
  
          p = {'type': 'unknown', 'tag': tag, 'raw': packet_data}
          if packet_type is not None:
              try:
                  p = packet_type(util.Reader(io.BytesIO(packet_data)))
                  p['tag'] = tag
              except ValueError:
                  log.exception('Skipping packet: %s', util.hexlify(packet_data))
  
          log.debug('packet "%s": %s', p['type'], p)
          yield p