docs: def findall(self, bs, start=None, end=None, count=None, bytealigned=None):
          """Find all occurrences of bs. Return generator of bit positions.
  
          bs -- The bitstring to find.
          start -- The bit position to start the search. Defaults to 0.
          end -- The bit position one past the last bit to search.
                 Defaults to self.len.
          count -- The maximum number of occurrences to find.
          bytealigned -- If True the bitstring will only be found on
                         byte boundaries.
  
          Raises ValueError if bs is empty, if start < 0, if end > self.len or
          if end < start.
  
          Note that all occurrences of bs are found, even if they overlap.
  
          """
          if count is not None and count < 0:
              raise ValueError("In findall, count must be >= 0.")
          bs = Bits(bs)
          start, end = self._validate_slice(start, end)
          if bytealigned is None:
              bytealigned = globals()['bytealigned']
          c = 0
          if bytealigned and not bs.len % 8 and not self._datastore.offset:
              # Use the quick find method
              f = self._findbytes
              x = bs._getbytes()
          else:
              f = self._findregex
              x = re.compile(bs._getbin())
          while True:
  
              p = f(x, start, end, bytealigned)
              if not p:
                  break
              if count is not None and c >= count:
                  return
              c += 1
              try:
                  self._pos = p[0]
              except AttributeError:
                  pass
              yield p[0]
              if bytealigned:
                  start = p[0] + 8
              else:
                  start = p[0] + 1
              if start >= end:
                  break
          return