# 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