def _raw_read(self, space, buffer, start, length): assert buffer is not None length = intmask(length) start = intmask(start) w_view = SimpleView(SubBuffer(buffer, start, length)).wrap(space) while True: try: w_size = space.call_method(self.w_raw, "readinto", w_view) except OperationError as e: if trap_eintr(space, e): continue # try again raise else: break if space.is_w(w_size, space.w_None): raise BlockingIOError() size = space.int_w(w_size) if size < 0 or size > length: raise oefmt( space.w_IOError, "raw readinto() returned invalid length %d (should " "have been between 0 and %d)", size, length) if self.abs_pos != -1: self.abs_pos += size return size
def _write(self, space, data): w_data = space.wrap(data) while True: try: w_written = space.call_method(self.w_raw, "write", w_data) except OperationError, e: if trap_eintr(space, e): continue # try again raise else: break
def _raw_read(self, space, buffer, start, length): length = intmask(length) w_buf = space.newbuffer(RawBuffer(buffer, start, length)) while True: try: w_size = space.call_method(self.w_raw, "readinto", w_buf) except OperationError, e: if trap_eintr(space, e): continue # try again raise else: break
def _ensure_data(self, space): while not self.decoded.has_data(): try: if not self._read_chunk(space): self.decoded.reset() self.snapshot = None return False except OperationError as e: if trap_eintr(space, e): continue raise return True
def _really_flush(self, space): pending_bytes = ''.join(self.pending_bytes) self.pending_bytes = None self.pending_bytes_count = 0 while True: try: space.call_method(self.w_buffer, "write", space.newbytes(pending_bytes)) except OperationError as e: if trap_eintr(space, e): continue raise else: break
def _writeflush(self, space): if not self.pending_bytes: return pending_bytes = ''.join(self.pending_bytes) self.pending_bytes = None self.pending_bytes_count = 0 while True: try: space.call_method(self.w_buffer, "write", space.newbytes(pending_bytes)) except OperationError as e: if trap_eintr(space, e): continue raise else: break
def read_w(self, space, w_size=None): self._check_attached(space) self._check_closed(space) if not self.w_decoder: raise oefmt(space.w_IOError, "not readable") size = convert_size(space, w_size) self._writeflush(space) if size < 0: # Read everything w_bytes = space.call_method(self.w_buffer, "read") w_decoded = space.call_method(self.w_decoder, "decode", w_bytes, space.w_True) check_decoded(space, w_decoded) w_result = space.newunicode(self._get_decoded_chars(-1)) w_final = space.add(w_result, w_decoded) self.snapshot = None return w_final remaining = size builder = UnicodeBuilder(size) # Keep reading chunks until we have n characters to return while True: data = self._get_decoded_chars(remaining) builder.append(data) remaining -= len(data) if remaining <= 0: # Done break try: if not self._read_chunk(space): # EOF break except OperationError as e: if trap_eintr(space, e): continue raise return space.newunicode(builder.build())
def read_w(self, space, w_size=None): self._check_attached(space) self._check_closed(space) if not self.w_decoder: raise oefmt(space.w_IOError, "not readable") size = convert_size(space, w_size) self._writeflush(space) if size < 0: # Read everything w_bytes = space.call_method(self.w_buffer, "read") w_decoded = space.call_method(self.w_decoder, "decode", w_bytes, space.w_True) check_decoded(space, w_decoded) w_result = space.wrap(self._get_decoded_chars(-1)) w_final = space.add(w_result, w_decoded) self.snapshot = None return w_final remaining = size builder = UnicodeBuilder(size) # Keep reading chunks until we have n characters to return while True: data = self._get_decoded_chars(remaining) builder.append(data) remaining -= len(data) if remaining <= 0: # Done break try: if not self._read_chunk(space): # EOF break except OperationError as e: if trap_eintr(space, e): continue raise return space.wrap(builder.build())
def _write(self, space, data): w_data = space.newbytes(data) while True: try: w_written = space.call_method(self.w_raw, "write", w_data) except OperationError as e: if trap_eintr(space, e): continue # try again raise else: break if space.is_w(w_written, space.w_None): # Non-blocking stream would have blocked. raise BlockingIOError() written = space.getindex_w(w_written, space.w_IOError) if not 0 <= written <= len(data): raise oefmt(space.w_IOError, "raw write() returned invalid length") if self.abs_pos != -1: self.abs_pos += written return written
def _raw_read(self, space, buffer, start, length): length = intmask(length) w_buf = space.newbuffer(RawBuffer(buffer, start, length)) while True: try: w_size = space.call_method(self.w_raw, "readinto", w_buf) except OperationError as e: if trap_eintr(space, e): continue # try again raise else: break if space.is_w(w_size, space.w_None): raise BlockingIOError() size = space.int_w(w_size) if size < 0 or size > length: raise oefmt(space.w_IOError, "raw readinto() returned invalid length %d (should " "have been between 0 and %d)", size, length) if self.abs_pos != -1: self.abs_pos += size return size
def readline_w(self, space, w_limit=None): self._check_attached(space) self._check_closed(space) self._writeflush(space) limit = convert_size(space, w_limit) chunked = 0 line = None remaining = None chunks = [] while True: # First, get some data if necessary has_data = True while not self.decoded_chars: try: if not self._read_chunk(space): has_data = False break except OperationError as e: if trap_eintr(space, e): continue raise if not has_data: # end of file self._set_decoded_chars(None) self.snapshot = None start = endpos = offset_to_buffer = 0 break if not remaining: line = self.decoded_chars start = self.decoded_chars_used offset_to_buffer = 0 else: assert self.decoded_chars_used == 0 line = remaining + self.decoded_chars start = 0 offset_to_buffer = len(remaining) remaining = None line_len = len(line) endpos, consumed = self._find_line_ending(line, start, line_len) if endpos >= 0: endpos += start if limit >= 0 and endpos >= start + limit - chunked: endpos = start + limit - chunked assert endpos >= 0 break assert consumed >= 0 # We can put aside up to `endpos` endpos = consumed + start if limit >= 0 and endpos >= start + limit - chunked: # Didn't find line ending, but reached length limit endpos = start + limit - chunked assert endpos >= 0 break # No line ending seen yet - put aside current data if endpos > start: s = line[start:endpos] chunks.append(s) chunked += len(s) # There may be some remaining bytes we'll have to prepend to the # next chunk of data if endpos < line_len: remaining = line[endpos:] line = None # We have consumed the buffer self._set_decoded_chars(None) if line: # Our line ends in the current buffer decoded_chars_used = endpos - offset_to_buffer assert decoded_chars_used >= 0 self.decoded_chars_used = decoded_chars_used if start > 0 or endpos < len(line): line = line[start:endpos] if remaining: chunks.append(remaining) remaining = None if chunks: if line: chunks.append(line) line = u''.join(chunks) if line: return space.newunicode(line) else: return space.newunicode(u'')
def readline_w(self, space, w_limit=None): self._check_attached(space) self._check_closed(space) self._writeflush(space) limit = convert_size(space, w_limit) chunked = 0 line = None remaining = None chunks = [] while True: # First, get some data if necessary has_data = True while not self.decoded_chars: try: if not self._read_chunk(space): has_data = False break except OperationError as e: if trap_eintr(space, e): continue raise if not has_data: # end of file self._set_decoded_chars(None) self.snapshot = None start = endpos = offset_to_buffer = 0 break if not remaining: line = self.decoded_chars start = self.decoded_chars_used offset_to_buffer = 0 else: assert self.decoded_chars_used == 0 line = remaining + self.decoded_chars start = 0 offset_to_buffer = len(remaining) remaining = None line_len = len(line) endpos, consumed = self._find_line_ending(line, start, line_len) if endpos >= 0: endpos += start if limit >= 0 and endpos >= start + limit - chunked: endpos = start + limit - chunked assert endpos >= 0 break assert consumed >= 0 # We can put aside up to `endpos` endpos = consumed + start if limit >= 0 and endpos >= start + limit - chunked: # Didn't find line ending, but reached length limit endpos = start + limit - chunked assert endpos >= 0 break # No line ending seen yet - put aside current data if endpos > start: s = line[start:endpos] chunks.append(s) chunked += len(s) # There may be some remaining bytes we'll have to prepend to the # next chunk of data if endpos < line_len: remaining = line[endpos:] line = None # We have consumed the buffer self._set_decoded_chars(None) if line: # Our line ends in the current buffer decoded_chars_used = endpos - offset_to_buffer assert decoded_chars_used >= 0 self.decoded_chars_used = decoded_chars_used if start > 0 or endpos < len(line): line = line[start:endpos] if remaining: chunks.append(remaining) remaining = None if chunks: if line: chunks.append(line) line = u''.join(chunks) if line: return space.wrap(line) else: return space.wrap(u'')