code: def SplitBuffer(buff, index=0, length=None):
    
    buffer_len = length or len(buff)
    while index < buffer_len:
      # data_index is the index where the data begins (i.e. after the tag).
      encoded_tag, data_index = ReadTag(buff, index)
  
      tag_type = ORD_MAP[encoded_tag[0]] & TAG_TYPE_MASK
      if tag_type == WIRETYPE_VARINT:
        # new_index is the index of the next tag.
        _, new_index = VarintReader(buff, data_index)
        yield (encoded_tag, b"", buff[data_index:new_index])
        index = new_index
  
      elif tag_type == WIRETYPE_FIXED64:
        yield (encoded_tag, b"", buff[data_index:data_index + 8])
        index = 8 + data_index
  
      elif tag_type == WIRETYPE_FIXED32:
        yield (encoded_tag, b"", buff[data_index:data_index + 4])
        index = 4 + data_index
  
      elif tag_type == WIRETYPE_LENGTH_DELIMITED:
        # Start index of the string.
        length, start = VarintReader(buff, data_index)
        yield (
            encoded_tag,
            buff[data_index:start],  # Encoded length.
            buff[start:start + length])  # Raw data of element.
        index = start + length
  
      else:
        raise rdfvalue.DecodeError("Unexpected Tag.")
docs: Parses the buffer as a prototypes.
  
    Args:
      buff: The buffer to parse.
      index: The position to start parsing.
      length: Optional length to parse until.
  
    Yields:
      Splits the buffer into tuples of strings:
          (encoded_tag, encoded_length, wire_format).