(self, n)
| 73 | self.byteSz += len(b) |
| 74 | |
| 75 | def get(self, n): |
| 76 | assert n <= self.byteSz, 'caller responsibility to ensure enough bytes' |
| 77 | |
| 78 | if (n == self.byteSz and len(self._dq) == 1 and |
| 79 | isinstance(self._dq[0], bytes)): |
| 80 | # Fast-path: if the deque has one element of the right |
| 81 | # size *and* type (fragmentation can result in 'buffer' |
| 82 | # objects pushed back on the deque) return it and avoid a |
| 83 | # copy. |
| 84 | self.byteSz = 0 |
| 85 | return self._dq.popleft() |
| 86 | |
| 87 | out = bytearray(n) |
| 88 | remaining = n |
| 89 | while remaining > 0: |
| 90 | part = memoryview(self._dq.popleft()) |
| 91 | delta = remaining - len(part) |
| 92 | offset = n - remaining |
| 93 | |
| 94 | if delta == 0: |
| 95 | out[offset:] = part |
| 96 | remaining = 0 |
| 97 | elif delta > 0: |
| 98 | out[offset:] = part |
| 99 | remaining = delta |
| 100 | elif delta < 0: |
| 101 | cleave = len(part) + delta |
| 102 | out[offset:] = part[:cleave] |
| 103 | self._dq.appendleft(part[cleave:]) |
| 104 | remaining = 0 |
| 105 | else: |
| 106 | assert False |
| 107 | |
| 108 | self.byteSz -= n |
| 109 | |
| 110 | assert len(out) == n |
| 111 | return bytes(out) |
| 112 | |
| 113 | def get_all(self): |
| 114 | return self.get(self.byteSz) |
no outgoing calls