示例#1
0
    def recvfrom_into_w(self, space, w_buffer, nbytes=0, flags=0):
        """recvfrom_into(buffer[, nbytes[, flags]]) -> (nbytes, address info)

        Like recv_into(buffer[, nbytes[, flags]]) but also return the sender's address info.
        """
        rwbuffer = space.writebuf_w(w_buffer)
        lgt = rwbuffer.getlength()
        if nbytes == 0:
            nbytes = lgt
        elif nbytes > lgt:
            raise oefmt(space.w_ValueError,
                        "nbytes is greater than the length of the buffer")
        try:
            rwbuffer.get_raw_address()
        except ValueError:
            rawbuf = RawByteBuffer(nbytes)
        else:
            rawbuf = rwbuffer
        while True:
            try:
                readlgt, addr = self.sock.recvfrom_into(rawbuf, nbytes, flags)
                break
            except SocketError as e:
                converted_error(space, e, eintr_retry=True)
        if rawbuf is not rwbuffer:
            rwbuffer.setslice(0, rawbuf.getslice(0, 1, readlgt))
        if addr:
            try:
                w_addr = addr_as_object(addr, self.sock.fd, space)
            except SocketError as e:
                raise converted_error(space, e)
        else:
            w_addr = space.w_None
        return space.newtuple([space.newint(readlgt), w_addr])
示例#2
0
    def recv_into_w(self, space, w_buffer, nbytes=0, flags=0):
        """recv_into(buffer, [nbytes[, flags]]) -> nbytes_read

        A version of recv() that stores its data into a buffer rather than creating
        a new string.  Receive up to buffersize bytes from the socket.  If buffersize
        is not specified (or 0), receive up to the size available in the given buffer.

        See recv() for documentation about the flags.
        """
        rwbuffer = space.writebuf_w(w_buffer)
        lgt = rwbuffer.getlength()
        if nbytes < 0:
            raise oefmt(space.w_ValueError, "negative buffersize in recv_into")
        if nbytes == 0:
            nbytes = lgt
        if lgt < nbytes:
            raise oefmt(space.w_ValueError,
                        "buffer too small for requested bytes")
        try:
            rwbuffer.get_raw_address()
        except ValueError:
            rawbuf = RawByteBuffer(nbytes)
        else:
            rawbuf = rwbuffer

        while True:
            try:
                nbytes_read = self.sock.recvinto(rawbuf, nbytes, flags)
                break
            except SocketError as e:
                converted_error(space, e, eintr_retry=True)
        if rawbuf is not rwbuffer:
            rwbuffer.setslice(0, rawbuf.getslice(0, 1, nbytes_read))
        return space.newint(nbytes_read)
示例#3
0
def do_recv_from_recvmsg_into(socket, buffersize, flags=0):
    l1 = buffersize // 2
    l2 = buffersize - l1
    buf1, buf2 = RawByteBuffer(l1), RawByteBuffer(l2)
    n, data, flag, address = socket.recvmsg_into([buf1, buf2], flags=flags)
    n1 = min(n, l1)
    n2 = n - n1
    return buf1.as_str()[:n1] + buf2.as_str()[:n2]
示例#4
0
def test_RawBufferView_basic():
    buf = RawByteBuffer(10)
    view = RawBufferView(buf, 'ignored', 2)
    assert view.getlength() == 10
    assert view.getformat() == 'ignored'
    assert view.getitemsize() == 2
    assert view.getndim() == 1
    assert view.getshape() == [5]
    assert view.getstrides() == [2]
    assert view.as_readbuf() is view.as_writebuf() is buf
示例#5
0
def test_SimpleView_basic():
    buf = RawByteBuffer(10)
    view = SimpleView(buf)
    assert view.getlength() == 10
    assert view.getformat() == 'B'
    assert view.getitemsize() == 1
    assert view.getndim() == 1
    assert view.getshape() == [10]
    assert view.getstrides() == [1]
    assert view.as_readbuf() is view.as_writebuf() is buf
示例#6
0
    def _init(self, space):
        if self.buffer_size <= 0:
            raise oefmt(space.w_ValueError,
                        "buffer size must be strictly positive")

        if space.config.translation.split_gc_address_space:
            # When using split GC address space, it is not possible to get the
            # raw address of a GC buffer. Therefore we use a buffer backed by
            # raw memory.
            self.buffer = RawByteBuffer(self.buffer_size)
        else:
            # TODO: test whether using the raw buffer is faster
            self.buffer = ByteBuffer(self.buffer_size)

        self.lock = TryLock(space)

        try:
            self._raw_tell(space)
        except OperationError:
            pass
示例#7
0
def do_recv_from_recvinto(socket, buffersize, flags=0):
    buf = RawByteBuffer(buffersize)
    read_bytes = socket.recvinto(buf, buffersize, flags=flags)
    return buf.as_str()[:read_bytes]
示例#8
0
    def recvmsg_into_w(self, space, w_buffers, ancbufsize=0, flags=0):
        """
        recvmsg_into(buffers[, ancbufsize[, flags]]) -> (nbytes, ancdata, msg_flags, address)

        Receive normal data and ancillary data from the socket, scattering the
        non-ancillary data into a series of buffers.  The buffers argument
        must be an iterable of objects that export writable buffers
        (e.g. bytearray objects); these will be filled with successive chunks
        of the non-ancillary data until it has all been written or there are
        no more buffers.  The ancbufsize argument sets the size in bytes of
        the internal buffer used to receive the ancillary data; it defaults to
        0, meaning that no ancillary data will be received.  Appropriate
        buffer sizes for ancillary data can be calculated using CMSG_SPACE()
        or CMSG_LEN(), and items which do not fit into the buffer might be
        truncated or discarded.  The flags argument defaults to 0 and has the
        same meaning as for recv().

        The return value is a 4-tuple: (nbytes, ancdata, msg_flags, address).
        The nbytes item is the total number of bytes of non-ancillary data
        written into the buffers.  The ancdata item is a list of zero or more
        tuples (cmsg_level, cmsg_type, cmsg_data) representing the ancillary
        data (control messages) received: cmsg_level and cmsg_type are
        integers specifying the protocol level and protocol-specific type
        respectively, and cmsg_data is a bytes object holding the associated
        data.  The msg_flags item is the bitwise OR of various flags
        indicating conditions on the received message; see your system
        documentation for details.  If the receiving socket is unconnected,
        address is the address of the sending socket, if available; otherwise,
        its value is unspecified.

        If recvmsg_into() raises an exception after the system call returns,
        it will first attempt to close any file descriptors received via the
        SCM_RIGHTS mechanism.
        """
        if ancbufsize < 0:
            raise oefmt(space.w_ValueError,
                        "invalid ancillary data buffer length")
        buffers_w = space.unpackiterable(w_buffers)
        buffers = [space.writebuf_w(w_buffer) for w_buffer in buffers_w]
        rawbufs = [None] * len(buffers)
        for i in range(len(buffers)):
            try:
                buffers[i].get_raw_address()
            except ValueError:
                rawbufs[i] = RawByteBuffer(buffers[i].getlength())
            else:
                rawbufs[i] = buffers[i]

        while True:
            try:
                recvtup = self.sock.recvmsg_into(rawbufs, ancbufsize, flags)
                nbytes, ancdata, retflag, address = recvtup
                w_nbytes = space.newint(nbytes)
                anclist = []
                for level, type, anc in ancdata:
                    w_tup = space.newtuple([
                        space.newint(level),
                        space.newint(type),
                        space.newbytes(anc)
                    ])
                    anclist.append(w_tup)

                w_anc = space.newlist(anclist)

                w_flag = space.newint(retflag)
                if (address is not None):
                    w_address = addr_as_object(recvtup[3], self.sock.fd, space)
                else:
                    w_address = space.w_None
                rettup = space.newtuple([w_nbytes, w_anc, w_flag, w_address])
                break
            except SocketError as e:
                converted_error(space, e, eintr_retry=True)

        n_remaining = nbytes
        for i in range(len(buffers)):
            lgt = rawbufs[i].getlength()
            n_read = min(lgt, n_remaining)
            n_remaining -= n_read
            if rawbufs[i] is not buffers[i]:
                buffers[i].setslice(0, rawbufs[i].getslice(0, 1, n_read))
            if n_remaining == 0:
                break
        return rettup