예제 #1
0
    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
예제 #2
0
 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
예제 #3
0
 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
예제 #4
0
 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
예제 #5
0
 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
예제 #6
0
 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
예제 #7
0
    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
예제 #8
0
    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
예제 #9
0
    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())
예제 #10
0
    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())
예제 #11
0
    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
예제 #12
0
    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
예제 #13
0
    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
예제 #14
0
    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'')
예제 #15
0
    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'')