# File lib/protocols/buftok.rb, line 49 49: def extract(data) 50: # Extract token-delimited entities from the input string with the split command. 51: # There's a bit of craftiness here with the -1 parameter. Normally split would 52: # behave no differently regardless of if the token lies at the very end of the 53: # input buffer or not (i.e. a literal edge case) Specifying -1 forces split to 54: # return "" in this case, meaning that the last entry in the list represents a 55: # new segment of data where the token has not been encountered 56: entities = data.split @delimiter, -1 57: 58: # Check to see if the buffer has exceeded capacity, if we're imposing a limit 59: if @size_limit 60: raise 'input buffer full' if @input_size + entities.first.size > @size_limit 61: @input_size += entities.first.size 62: end 63: 64: # Move the first entry in the resulting array into the input buffer. It represents 65: # the last segment of a token-delimited entity unless it's the only entry in the list. 66: @input << entities.shift 67: 68: # If the resulting array from the split is empty, the token was not encountered 69: # (not even at the end of the buffer). Since we've encountered no token-delimited 70: # entities this go-around, return an empty array. 71: return [] if entities.empty? 72: 73: # At this point, we've hit a token, or potentially multiple tokens. Now we can bring 74: # together all the data we've buffered from earlier calls without hitting a token, 75: # and add it to our list of discovered entities. 76: entities.unshift @input.join 77: 78: ?? 79: 80: # Now that we've hit a token, joined the input buffer and added it to the entities 81: # list, we can go ahead and clear the input buffer. All of the segments that were 82: # stored before the join can now be garbage collected. 83: @input.clear 84: 85: # The last entity in the list is not token delimited, however, thanks to the -1 86: # passed to split. It represents the beginning of a new list of as-yet-untokenized 87: # data, so we add it to the start of the list. 88: @input << entities.pop 89: 90: # Set the new input buffer size, provided we're keeping track 91: @input_size = @input.first.size if @size_limit 92: 93: # Now we're left with the list of extracted token-delimited entities we wanted 94: # in the first place. Hooray! 95: entities 96: end