| 40 | |
| 41 | |
| 42 | class IteratorByteStream(SyncByteStream): |
| 43 | CHUNK_SIZE = 65_536 |
| 44 | |
| 45 | def __init__(self, stream: Iterable[bytes]) -> None: |
| 46 | self._stream = stream |
| 47 | self._is_stream_consumed = False |
| 48 | self._is_generator = inspect.isgenerator(stream) |
| 49 | |
| 50 | def __iter__(self) -> Iterator[bytes]: |
| 51 | if self._is_stream_consumed and self._is_generator: |
| 52 | raise StreamConsumed() |
| 53 | |
| 54 | self._is_stream_consumed = True |
| 55 | if hasattr(self._stream, "read"): |
| 56 | # File-like interfaces should use 'read' directly. |
| 57 | chunk = self._stream.read(self.CHUNK_SIZE) |
| 58 | while chunk: |
| 59 | yield chunk |
| 60 | chunk = self._stream.read(self.CHUNK_SIZE) |
| 61 | else: |
| 62 | # Otherwise iterate. |
| 63 | for part in self._stream: |
| 64 | yield part |
| 65 | |
| 66 | |
| 67 | class AsyncIteratorByteStream(AsyncByteStream): |