| 223 | self._raw.seek(0) |
| 224 | |
| 225 | def read(self, size=None): |
| 226 | # Normalize "read all" size values to None |
| 227 | if size is not None and size <= 0: |
| 228 | size = None |
| 229 | |
| 230 | # If the underlying body is done and we have nothing left then |
| 231 | # end the stream |
| 232 | if self._complete and not self._remaining: |
| 233 | return b"" |
| 234 | |
| 235 | # While we're not done and want more bytes |
| 236 | want_more_bytes = size is None or size > len(self._remaining) |
| 237 | while not self._complete and want_more_bytes: |
| 238 | self._remaining += self._make_chunk() |
| 239 | want_more_bytes = size is None or size > len(self._remaining) |
| 240 | |
| 241 | # If size was None, we want to return everything |
| 242 | if size is None: |
| 243 | size = len(self._remaining) |
| 244 | |
| 245 | # Return a chunk up to the size asked for |
| 246 | to_return = self._remaining[:size] |
| 247 | self._remaining = self._remaining[size:] |
| 248 | return to_return |
| 249 | |
| 250 | def _make_chunk(self): |
| 251 | # NOTE: Chunk size is not deterministic as read could return less. This |