docs: def hexdump_iter(logger, fd, width=16, skip=True, hexii=False, begin=0, highlight=None):
      r"""
      Return a hexdump-dump of a string as a generator of lines.  Unless you have
      massive amounts of data you probably want to use :meth:`hexdump`.
  
      Arguments:
          logger(FastLogger): Logger object
          fd(file): File object to dump.  Use :meth:`StringIO.StringIO` or :meth:`hexdump` to dump a string.
          width(int): The number of characters per line
          skip(bool): Set to True, if repeated lines should be replaced by a "*"
          hexii(bool): Set to True, if a hexii-dump should be returned instead of a hexdump.
          begin(int):  Offset of the first byte to print in the left column
          highlight(iterable): Byte values to highlight.
  
      Returns:
          A generator producing the hexdump-dump one line at a time.
      """
      style     = logger.style.hexdump.copy()
      highlight = highlight or []
  
      for b in highlight:
          if isinstance(b, str):
              b = ord(b)
          style['%02x' % b] = style['highlight']
  
      _style = style
  
      skipping    = False
      lines       = []
      last_unique = ''
      byte_width  = len('00 ')
      column_sep  = '  '
      line_fmt    = '%%(offset)08x  %%(hexbytes)-%is │%%(printable)s│' % (len(column_sep)+(width*byte_width))
      spacer      = ' '
      marker      = (style.get('marker') or (lambda s:s))('│')
  
      if hexii:
          column_sep = ''
          line_fmt   = '%%(offset)08x  %%(hexbytes)-%is│' % (len(column_sep)+(width*byte_width))
      else:
          def style_byte(b):
              hbyte = '%02x' % ord(b)
              abyte = b if isprint(b) else '·'
              if hbyte in style:
                  st = style[hbyte]
              elif isprint(b):
                  st = style.get('printable')
              else:
                  st = style.get('nonprintable')
              if st:
                  hbyte = st(hbyte)
                  abyte = st(abyte)
              return hbyte, abyte
          cache = [style_byte(chr(b)) for b in range(256)]
  
      numb = 0
      while True:
          offset = begin + numb
  
          # If a tube is passed in as fd, it will raise EOFError when it runs
          # out of data, unlike a file or StringIO object, which return an empty
          # string.
          try:
              chunk = fd.read(width)
          except EOFError:
              chunk = ''
  
          # We have run out of data, exit the loop
          if chunk == '':
              break
  
          # Advance the cursor by the number of bytes we actually read
          numb += len(chunk)
  
          # If this chunk is the same as the last unique chunk,
          # use a '*' instead.
          if skip and last_unique:
              same_as_last_line = (last_unique == chunk)
              lines_are_sequential = False
              last_unique = chunk
  
              if same_as_last_line or lines_are_sequential:
  
                  # If we have not already printed a "*", do so
                  if not skipping:
                      yield '*'
                      skipping = True
  
                  # Move on to the next chunk
                  continue
  
          # Chunk is unique, no longer skipping
          skipping = False
          last_unique = chunk
  
          # Generate contents for line
          hexbytes = ''
          printable = ''
          for i, b in enumerate(chunk):
              if not hexii:
                  hbyte, abyte = cache[ord(b)]
              else:
                  hbyte, abyte = _hexiichar(b), ''
  
              if i % 4 == 3 and i < width - 1:
                  hbyte += spacer
                  abyte += marker
  
              hexbytes += hbyte + ' '
              printable += abyte
  
          if i + 1 < width:
              delta = width - i - 1
  
              # How many hex-bytes would we have printed?
              count = byte_width * delta
  
              # How many dividers do we need to fill out the line?
              dividers_per_line = (width // 4) - (1 if width % 4 == 0 else 0)
              dividers_printed = (i // 4) + (1 if i % 4 == 3 else 0)
              count += dividers_per_line - dividers_printed
  
              hexbytes += ' ' * count
  
          # Python2 -> 3 wew
          if isinstance(line_fmt, six.binary_type):
              line_fmt = line_fmt.decode('utf-8')
          if isinstance(offset, six.binary_type):
              offset = printable.decode('utf-8')
          
          line = line_fmt % {'offset': offset, 'hexbytes': hexbytes, 'printable': printable}
          yield line
  
      line = "%08x" % (begin + numb)
      yield line