def process(self, buff):
        '''
            Process the input buffer. The buffer can contains all or a segment of the bytes from the complete message. 
            The function will buffer what will require extra bytes to be processed. 
        :param buff:
        '''
        
        # adding the current to the available
        self.memory = self.memory + buff 
        self._available = len(self.memory)
        idx = 0
        # prepare pointers and inputs
        # read first byte 
        
        handleheader = self.handle_read_header
        handlelength = self.handle_read_length
        handlevalue = self.handle_read_value
        handleegend = self.handle_segment_ended
        # process input while exists
        while self._available >= self._advance:
            # expected start of a new segment
            if self._scstate.value <= ScannerState.WAITING_FOR_HEADER.value:
                self._advance = 1
                handleheader(self.memory[idx])
            # the scanner expects to read one or multiple bytes that contain an 
            # integer contain the length of the value to be expected
            elif self._scstate is ScannerState.WAITING_FOR_LENGTH:
                self._advance = self._state[3]
                # breaking if not available
                if self._available < self._state[3]:
                    break
                handlelength(self.memory, idx, idx + self._advance)
                # if the scanner is expecting to parse one or multiple bytes as the value of the segment
            elif self._scstate is ScannerState.WAITING_FOR_VALUE:
                self._advance = self._state[3]
                if self._available < self._advance:
                    break
                handlevalue(self.memory, idx, idx + self._advance)
            # if the scanner is expecting to parse an extension
            elif self._scstate is ScannerState.WAITING_FOR_EXT_TYPE:
                self._advance = 1
                self.handle_read_ext_type(self.memory, idx)
            
            # if a data segment is ended
            if self._scstate is ScannerState.SEGMENT_ENDED:
                handleegend()
            # proceed with scanning
            
            self._available -= self._advance   
            idx = idx + self._advance
            self._advance = 1
        
        #  finished processing all since it needed extra info     
        self.memory = buffer(self.memory, idx, len(self.memory))