(self)
| 119 | # if found, transition to the next state. |
| 120 | |
| 121 | def handle_read(self): |
| 122 | |
| 123 | try: |
| 124 | data = self.recv(self.ac_in_buffer_size) |
| 125 | except BlockingIOError: |
| 126 | return |
| 127 | except OSError: |
| 128 | self.handle_error() |
| 129 | return |
| 130 | |
| 131 | if isinstance(data, str) and self.use_encoding: |
| 132 | data = bytes(str, self.encoding) |
| 133 | self.ac_in_buffer = self.ac_in_buffer + data |
| 134 | |
| 135 | # Continue to search for self.terminator in self.ac_in_buffer, |
| 136 | # while calling self.collect_incoming_data. The while loop |
| 137 | # is necessary because we might read several data+terminator |
| 138 | # combos with a single recv(4096). |
| 139 | |
| 140 | while self.ac_in_buffer: |
| 141 | lb = len(self.ac_in_buffer) |
| 142 | terminator = self.get_terminator() |
| 143 | if not terminator: |
| 144 | # no terminator, collect it all |
| 145 | self.collect_incoming_data(self.ac_in_buffer) |
| 146 | self.ac_in_buffer = b'' |
| 147 | elif isinstance(terminator, int): |
| 148 | # numeric terminator |
| 149 | n = terminator |
| 150 | if lb < n: |
| 151 | self.collect_incoming_data(self.ac_in_buffer) |
| 152 | self.ac_in_buffer = b'' |
| 153 | self.terminator = self.terminator - lb |
| 154 | else: |
| 155 | self.collect_incoming_data(self.ac_in_buffer[:n]) |
| 156 | self.ac_in_buffer = self.ac_in_buffer[n:] |
| 157 | self.terminator = 0 |
| 158 | self.found_terminator() |
| 159 | else: |
| 160 | # 3 cases: |
| 161 | # 1) end of buffer matches terminator exactly: |
| 162 | # collect data, transition |
| 163 | # 2) end of buffer matches some prefix: |
| 164 | # collect data to the prefix |
| 165 | # 3) end of buffer does not match any prefix: |
| 166 | # collect data |
| 167 | terminator_len = len(terminator) |
| 168 | index = self.ac_in_buffer.find(terminator) |
| 169 | if index != -1: |
| 170 | # we found the terminator |
| 171 | if index > 0: |
| 172 | # don't bother reporting the empty string |
| 173 | # (source of subtle bugs) |
| 174 | self.collect_incoming_data(self.ac_in_buffer[:index]) |
| 175 | self.ac_in_buffer = self.ac_in_buffer[index+terminator_len:] |
| 176 | # This does the Right Thing if the terminator |
| 177 | # is changed here. |
| 178 | self.found_terminator() |
nothing calls this directly
no test coverage detected