code: def read(self, n):
          
          buf = self._read_buf
          pos = self._read_pos
          end = pos + n
  
          if end <= len(buf):
              # Fast path: the data to read is fully buffered.
              self._read_pos += n
              return self._update_pos(buf[pos:end])
  
          # Slow path: read from the stream until enough bytes are read,
          # or until an EOF occurs or until read() would block.
          wanted = max(self.buffer_size, n)
          while len(buf) < end:
              chunk = self.raw.read(wanted)
              if not chunk:
                  break
              buf += chunk
  
          self._read_buf = buf[end:]  # Save the extra data in the buffer.
          self._read_pos = 0
          return self._update_pos(buf[pos:end])
docs: Read n bytes.
          Returns exactly n bytes of data unless the underlying raw IO
          stream reaches EOF.