Fixes in struct and socket from merge reviews.
- Following Guido's comments, renamed * pack_to -> pack_into * recv_buf -> recv_into * recvfrom_buf -> recvfrom_into - Made fixes to _struct.c according to Neal Norwitz comments on the checkins list. - Converted some ints into the appropriate -- I hope -- ssize_t and size_t.
This commit is contained in:
parent
63f0db682e
commit
af2ae72cb2
|
@ -141,7 +141,7 @@ class _socketobject(object):
|
|||
__doc__ = _realsocket.__doc__
|
||||
|
||||
__slots__ = ["_sock",
|
||||
"recv", "recv_buf", "recvfrom_buf",
|
||||
"recv", "recv_into", "recvfrom_into",
|
||||
"send", "sendto", "recvfrom",
|
||||
"__weakref__"]
|
||||
|
||||
|
@ -151,10 +151,10 @@ class _socketobject(object):
|
|||
self._sock = _sock
|
||||
self.send = self._sock.send
|
||||
self.recv = self._sock.recv
|
||||
self.recv_buf = self._sock.recv_buf
|
||||
self.recv_into = self._sock.recv_into
|
||||
self.sendto = self._sock.sendto
|
||||
self.recvfrom = self._sock.recvfrom
|
||||
self.recvfrom_buf = self._sock.recvfrom_buf
|
||||
self.recvfrom_into = self._sock.recvfrom_into
|
||||
|
||||
def close(self):
|
||||
self._sock = _closedsocket()
|
||||
|
|
|
@ -62,7 +62,7 @@ def pack(fmt, *args):
|
|||
o = _compile(fmt)
|
||||
return o.pack(*args)
|
||||
|
||||
def pack_to(fmt, buf, offset, *args):
|
||||
def pack_into(fmt, buf, offset, *args):
|
||||
"""
|
||||
Pack the values v2, v2, ... according to fmt, write
|
||||
the packed bytes into the writable buffer buf starting at offset.
|
||||
|
@ -72,7 +72,7 @@ def pack_to(fmt, buf, offset, *args):
|
|||
o = _cache[fmt]
|
||||
except KeyError:
|
||||
o = _compile(fmt)
|
||||
return o.pack_to(buf, offset, *args)
|
||||
return o.pack_into(buf, offset, *args)
|
||||
|
||||
def unpack(fmt, s):
|
||||
"""
|
||||
|
|
|
@ -860,25 +860,25 @@ class BufferIOTest(SocketConnectedTest):
|
|||
def __init__(self, methodName='runTest'):
|
||||
SocketConnectedTest.__init__(self, methodName=methodName)
|
||||
|
||||
def testRecvBuf(self):
|
||||
def testRecvInto(self):
|
||||
buf = array.array('c', ' '*1024)
|
||||
nbytes = self.cli_conn.recv_buf(buf)
|
||||
nbytes = self.cli_conn.recv_into(buf)
|
||||
self.assertEqual(nbytes, len(MSG))
|
||||
msg = buf.tostring()[:len(MSG)]
|
||||
self.assertEqual(msg, MSG)
|
||||
|
||||
def _testRecvBuf(self):
|
||||
def _testRecvInto(self):
|
||||
buf = buffer(MSG)
|
||||
self.serv_conn.send(buf)
|
||||
|
||||
def testRecvFromBuf(self):
|
||||
def testRecvFromInto(self):
|
||||
buf = array.array('c', ' '*1024)
|
||||
nbytes, addr = self.cli_conn.recvfrom_buf(buf)
|
||||
nbytes, addr = self.cli_conn.recvfrom_into(buf)
|
||||
self.assertEqual(nbytes, len(MSG))
|
||||
msg = buf.tostring()[:len(MSG)]
|
||||
self.assertEqual(msg, MSG)
|
||||
|
||||
def _testRecvFromBuf(self):
|
||||
def _testRecvFromInto(self):
|
||||
buf = buffer(MSG)
|
||||
self.serv_conn.send(buf)
|
||||
|
||||
|
|
|
@ -529,50 +529,50 @@ def test_unpack_from():
|
|||
for i in xrange(6, len(test_string) + 1):
|
||||
simple_err(struct.unpack_from, fmt, data, i)
|
||||
|
||||
def test_pack_to():
|
||||
def test_pack_into():
|
||||
test_string = 'Reykjavik rocks, eow!'
|
||||
writable_buf = array.array('c', ' '*100)
|
||||
fmt = '21s'
|
||||
s = struct.Struct(fmt)
|
||||
|
||||
# Test without offset
|
||||
s.pack_to(writable_buf, 0, test_string)
|
||||
s.pack_into(writable_buf, 0, test_string)
|
||||
from_buf = writable_buf.tostring()[:len(test_string)]
|
||||
assert from_buf == test_string
|
||||
|
||||
# Test with offset.
|
||||
s.pack_to(writable_buf, 10, test_string)
|
||||
s.pack_into(writable_buf, 10, test_string)
|
||||
from_buf = writable_buf.tostring()[:len(test_string)+10]
|
||||
assert from_buf == (test_string[:10] + test_string)
|
||||
|
||||
# Go beyond boundaries.
|
||||
small_buf = array.array('c', ' '*10)
|
||||
assertRaises(struct.error, s.pack_to, small_buf, 0, test_string)
|
||||
assertRaises(struct.error, s.pack_to, small_buf, 2, test_string)
|
||||
assertRaises(struct.error, s.pack_into, small_buf, 0, test_string)
|
||||
assertRaises(struct.error, s.pack_into, small_buf, 2, test_string)
|
||||
|
||||
def test_pack_to_fn():
|
||||
def test_pack_into_fn():
|
||||
test_string = 'Reykjavik rocks, eow!'
|
||||
writable_buf = array.array('c', ' '*100)
|
||||
fmt = '21s'
|
||||
pack_to = lambda *args: struct.pack_to(fmt, *args)
|
||||
pack_into = lambda *args: struct.pack_into(fmt, *args)
|
||||
|
||||
# Test without offset
|
||||
pack_to(writable_buf, 0, test_string)
|
||||
pack_into(writable_buf, 0, test_string)
|
||||
from_buf = writable_buf.tostring()[:len(test_string)]
|
||||
assert from_buf == test_string
|
||||
|
||||
# Test with offset.
|
||||
pack_to(writable_buf, 10, test_string)
|
||||
pack_into(writable_buf, 10, test_string)
|
||||
from_buf = writable_buf.tostring()[:len(test_string)+10]
|
||||
assert from_buf == (test_string[:10] + test_string)
|
||||
|
||||
# Go beyond boundaries.
|
||||
small_buf = array.array('c', ' '*10)
|
||||
assertRaises(struct.error, pack_to, small_buf, 0, test_string)
|
||||
assertRaises(struct.error, pack_to, small_buf, 2, test_string)
|
||||
assertRaises(struct.error, pack_into, small_buf, 0, test_string)
|
||||
assertRaises(struct.error, pack_into, small_buf, 2, test_string)
|
||||
|
||||
|
||||
# Test methods to pack and unpack from buffers rather than strings.
|
||||
test_unpack_from()
|
||||
test_pack_to()
|
||||
test_pack_to_fn()
|
||||
test_pack_into()
|
||||
test_pack_into_fn()
|
||||
|
|
|
@ -1572,8 +1572,7 @@ s_pack(PyObject *self, PyObject *args)
|
|||
soself = (PyStructObject *)self;
|
||||
assert(PyStruct_Check(self));
|
||||
assert(soself->s_codes != NULL);
|
||||
if (args == NULL || !PyTuple_Check(args) ||
|
||||
PyTuple_GET_SIZE(args) != soself->s_len)
|
||||
if (PyTuple_GET_SIZE(args) != soself->s_len)
|
||||
{
|
||||
PyErr_Format(StructError,
|
||||
"pack requires exactly %zd arguments", soself->s_len);
|
||||
|
@ -1594,16 +1593,16 @@ s_pack(PyObject *self, PyObject *args)
|
|||
return result;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(s_pack_to__doc__,
|
||||
"S.pack_to(buffer, offset, v1, v2, ...)\n\
|
||||
PyDoc_STRVAR(s_pack_into__doc__,
|
||||
"S.pack_into(buffer, offset, v1, v2, ...)\n\
|
||||
\n\
|
||||
Pack the values v2, v2, ... according to this Struct's format, write \n\
|
||||
Pack the values v1, v2, ... according to this Struct's format, write \n\
|
||||
the packed bytes into the writable buffer buf starting at offset. Note\n\
|
||||
that the offset is not an optional argument. See struct.__doc__ for \n\
|
||||
more on format strings.");
|
||||
|
||||
static PyObject *
|
||||
s_pack_to(PyObject *self, PyObject *args)
|
||||
s_pack_into(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyStructObject *soself;
|
||||
char *buffer;
|
||||
|
@ -1613,11 +1612,10 @@ s_pack_to(PyObject *self, PyObject *args)
|
|||
soself = (PyStructObject *)self;
|
||||
assert(PyStruct_Check(self));
|
||||
assert(soself->s_codes != NULL);
|
||||
if (args == NULL || !PyTuple_Check(args) ||
|
||||
PyTuple_GET_SIZE(args) != (soself->s_len + 2))
|
||||
if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
|
||||
{
|
||||
PyErr_Format(StructError,
|
||||
"pack_to requires exactly %zd arguments",
|
||||
"pack_into requires exactly %zd arguments",
|
||||
(soself->s_len + 2));
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1630,7 +1628,7 @@ s_pack_to(PyObject *self, PyObject *args)
|
|||
assert( buffer_len >= 0 );
|
||||
|
||||
/* Extract the offset from the first argument */
|
||||
offset = PyInt_AsLong(PyTuple_GET_ITEM(args, 1));
|
||||
offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
|
||||
|
||||
/* Support negative offsets. */
|
||||
if (offset < 0)
|
||||
|
@ -1639,7 +1637,7 @@ s_pack_to(PyObject *self, PyObject *args)
|
|||
/* Check boundaries */
|
||||
if (offset < 0 || (buffer_len - offset) < soself->s_size) {
|
||||
PyErr_Format(StructError,
|
||||
"pack_to requires a buffer of at least %zd bytes",
|
||||
"pack_into requires a buffer of at least %zd bytes",
|
||||
soself->s_size);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1668,10 +1666,10 @@ s_get_size(PyStructObject *self, void *unused)
|
|||
/* List of functions */
|
||||
|
||||
static struct PyMethodDef s_methods[] = {
|
||||
{"pack", (PyCFunction)s_pack, METH_VARARGS, s_pack__doc__},
|
||||
{"pack_to", (PyCFunction)s_pack_to, METH_VARARGS, s_pack_to__doc__},
|
||||
{"unpack", (PyCFunction)s_unpack, METH_O, s_unpack__doc__},
|
||||
{"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS, s_unpack_from__doc__},
|
||||
{"pack", s_pack, METH_VARARGS, s_pack__doc__},
|
||||
{"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
|
||||
{"unpack", s_unpack, METH_O, s_unpack__doc__},
|
||||
{"unpack_from", s_unpack_from, METH_KEYWORDS, s_unpack_from__doc__},
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
|
|
@ -104,9 +104,9 @@ gettimeout() -- return timeout or None\n\
|
|||
listen(n) -- start listening for incoming connections\n\
|
||||
makefile([mode, [bufsize]]) -- return a file object for the socket [*]\n\
|
||||
recv(buflen[, flags]) -- receive data\n\
|
||||
recv_buf(buffer[, nbytes[, flags]]) -- receive data (into a buffer)\n\
|
||||
recv_into(buffer[, nbytes[, flags]]) -- receive data (into a buffer)\n\
|
||||
recvfrom(buflen[, flags]) -- receive data and sender\'s address\n\
|
||||
recvfrom_buf(buffer[, nbytes, [, flags])\n\
|
||||
recvfrom_into(buffer[, nbytes, [, flags])\n\
|
||||
-- receive data and sender\'s address (into a buffer)\n\
|
||||
sendall(data[, flags]) -- send all data\n\
|
||||
send(data[, flags]) -- send data, may not send all of it\n\
|
||||
|
@ -2139,17 +2139,18 @@ The mode and buffersize arguments are as for the built-in open() function.");
|
|||
#endif /* NO_DUP */
|
||||
|
||||
/*
|
||||
* This is the guts of the recv() and recv_buf() methods, which reads into a
|
||||
* This is the guts of the recv() and recv_into() methods, which reads into a
|
||||
* char buffer. If you have any inc/def ref to do to the objects that contain
|
||||
* the buffer, do it in the caller. This function returns the number of bytes
|
||||
* succesfully read. If there was an error, it returns -1. Note that it is
|
||||
* also possible that we return a number of bytes smaller than the request
|
||||
* bytes.
|
||||
*/
|
||||
static int
|
||||
static ssize_t
|
||||
sock_recv_guts(PySocketSockObject *s, char* cbuf, int len, int flags)
|
||||
{
|
||||
int timeout, outlen = 0;
|
||||
ssize_t outlen = 0;
|
||||
int timeout;
|
||||
#ifdef __VMS
|
||||
int remaining, nread;
|
||||
char *read_buf;
|
||||
|
@ -2225,7 +2226,8 @@ sock_recv_guts(PySocketSockObject *s, char* cbuf, int len, int flags)
|
|||
static PyObject *
|
||||
sock_recv(PySocketSockObject *s, PyObject *args)
|
||||
{
|
||||
int recvlen, flags = 0, outlen;
|
||||
int recvlen, flags = 0;
|
||||
ssize_t outlen;
|
||||
PyObject *buf;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "i|i:recv", &recvlen, &flags))
|
||||
|
@ -2243,7 +2245,7 @@ sock_recv(PySocketSockObject *s, PyObject *args)
|
|||
return NULL;
|
||||
|
||||
/* Call the guts */
|
||||
outlen = sock_recv_guts(s, PyString_AsString(buf), recvlen, flags);
|
||||
outlen = sock_recv_guts(s, PyString_AS_STRING(buf), recvlen, flags);
|
||||
if (outlen < 0) {
|
||||
/* An error occured, release the string and return an
|
||||
error. */
|
||||
|
@ -2270,19 +2272,20 @@ at least one byte is available or until the remote end is closed. When\n\
|
|||
the remote end is closed and all data is read, return the empty string.");
|
||||
|
||||
|
||||
/* s.recv_buf(buffer, [nbytes [,flags]]) method */
|
||||
/* s.recv_into(buffer, [nbytes [,flags]]) method */
|
||||
|
||||
static PyObject*
|
||||
sock_recv_buf(PySocketSockObject *s, PyObject *args, PyObject *kwds)
|
||||
sock_recv_into(PySocketSockObject *s, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
static char *kwlist[] = {"buffer", "nbytes", "flags", 0};
|
||||
|
||||
int recvlen = 0, flags = 0, readlen;
|
||||
int recvlen = 0, flags = 0;
|
||||
ssize_t readlen;
|
||||
char *buf;
|
||||
int buflen;
|
||||
|
||||
/* Get the buffer's memory */
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#|ii:recv", kwlist,
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "w#|ii:recv", kwlist,
|
||||
&buf, &buflen, &recvlen, &flags))
|
||||
return NULL;
|
||||
assert(buf != 0 && buflen > 0);
|
||||
|
@ -2313,11 +2316,11 @@ sock_recv_buf(PySocketSockObject *s, PyObject *args, PyObject *kwds)
|
|||
|
||||
/* Return the number of bytes read. Note that we do not do anything
|
||||
special here in the case that readlen < recvlen. */
|
||||
return PyInt_FromLong(readlen);
|
||||
return PyInt_FromSsize_t(readlen);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(recv_buf_doc,
|
||||
"recv_buf(buffer, [nbytes[, flags]]) -> nbytes_read\n\
|
||||
PyDoc_STRVAR(recv_into_doc,
|
||||
"recv_into(buffer, [nbytes[, flags]]) -> nbytes_read\n\
|
||||
\n\
|
||||
A version of recv() that stores its data into a buffer rather than creating \n\
|
||||
a new string. Receive up to buffersize bytes from the socket. If buffersize \n\
|
||||
|
@ -2327,7 +2330,7 @@ See recv() for documentation about the flags.");
|
|||
|
||||
|
||||
/*
|
||||
* This is the guts of the recv() and recv_buf() methods, which reads into a
|
||||
* This is the guts of the recv() and recv_into() methods, which reads into a
|
||||
* char buffer. If you have any inc/def ref to do to the objects that contain
|
||||
* the buffer, do it in the caller. This function returns the number of bytes
|
||||
* succesfully read. If there was an error, it returns -1. Note that it is
|
||||
|
@ -2337,12 +2340,13 @@ See recv() for documentation about the flags.");
|
|||
* 'addr' is a return value for the address object. Note that you must decref
|
||||
* it yourself.
|
||||
*/
|
||||
static int
|
||||
static ssize_t
|
||||
sock_recvfrom_guts(PySocketSockObject *s, char* cbuf, int len, int flags,
|
||||
PyObject** addr)
|
||||
{
|
||||
sock_addr_t addrbuf;
|
||||
int n = 0, timeout;
|
||||
int timeout;
|
||||
ssize_t n = 0;
|
||||
socklen_t addrlen;
|
||||
|
||||
*addr = NULL;
|
||||
|
@ -2398,7 +2402,8 @@ sock_recvfrom(PySocketSockObject *s, PyObject *args)
|
|||
PyObject *buf = NULL;
|
||||
PyObject *addr = NULL;
|
||||
PyObject *ret = NULL;
|
||||
int recvlen, outlen, flags = 0;
|
||||
int recvlen, flags = 0;
|
||||
ssize_t outlen;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "i|i:recvfrom", &recvlen, &flags))
|
||||
return NULL;
|
||||
|
@ -2435,21 +2440,22 @@ PyDoc_STRVAR(recvfrom_doc,
|
|||
Like recv(buffersize, flags) but also return the sender's address info.");
|
||||
|
||||
|
||||
/* s.recvfrom_buf(buffer[, nbytes [,flags]]) method */
|
||||
/* s.recvfrom_into(buffer[, nbytes [,flags]]) method */
|
||||
|
||||
static PyObject *
|
||||
sock_recvfrom_buf(PySocketSockObject *s, PyObject *args, PyObject* kwds)
|
||||
sock_recvfrom_into(PySocketSockObject *s, PyObject *args, PyObject* kwds)
|
||||
{
|
||||
static char *kwlist[] = {"buffer", "nbytes", "flags", 0};
|
||||
|
||||
int recvlen = 0, flags = 0, readlen;
|
||||
int recvlen = 0, flags = 0;
|
||||
ssize_t readlen;
|
||||
char *buf;
|
||||
int buflen;
|
||||
|
||||
PyObject *addr = NULL;
|
||||
PyObject *ret = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s#|ii:recvfrom", kwlist,
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "w#|ii:recvfrom", kwlist,
|
||||
&buf, &buflen, &recvlen, &flags))
|
||||
return NULL;
|
||||
assert(buf != 0 && buflen > 0);
|
||||
|
@ -2467,22 +2473,19 @@ sock_recvfrom_buf(PySocketSockObject *s, PyObject *args, PyObject* kwds)
|
|||
readlen = sock_recvfrom_guts(s, buf, recvlen, flags, &addr);
|
||||
if (readlen < 0) {
|
||||
/* Return an error */
|
||||
goto finally;
|
||||
Py_XDECREF(addr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return the number of bytes read and the address. Note that we do
|
||||
not do anything special here in the case that readlen < recvlen. */
|
||||
ret = Py_BuildValue("lO", readlen, addr);
|
||||
|
||||
finally:
|
||||
Py_XDECREF(addr);
|
||||
return ret;
|
||||
return Py_BuildValue("lO", readlen, addr);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(recvfrom_buf_doc,
|
||||
"recvfrom_buf(buffer[, nbytes[, flags]]) -> (nbytes, address info)\n\
|
||||
PyDoc_STRVAR(recvfrom_into_doc,
|
||||
"recvfrom_into(buffer[, nbytes[, flags]]) -> (nbytes, address info)\n\
|
||||
\n\
|
||||
Like recv_buf(buffer[, nbytes[, flags]]) but also return the sender's address info.");
|
||||
Like recv_into(buffer[, nbytes[, flags]]) but also return the sender's address info.");
|
||||
|
||||
|
||||
/* s.send(data [,flags]) method */
|
||||
|
@ -2711,12 +2714,12 @@ static PyMethodDef sock_methods[] = {
|
|||
#endif
|
||||
{"recv", (PyCFunction)sock_recv, METH_VARARGS,
|
||||
recv_doc},
|
||||
{"recv_buf", (PyCFunction)sock_recv_buf, METH_VARARGS | METH_KEYWORDS,
|
||||
recv_buf_doc},
|
||||
{"recv_into", (PyCFunction)sock_recv_into, METH_VARARGS | METH_KEYWORDS,
|
||||
recv_into_doc},
|
||||
{"recvfrom", (PyCFunction)sock_recvfrom, METH_VARARGS,
|
||||
recvfrom_doc},
|
||||
{"recvfrom_buf", (PyCFunction)sock_recvfrom_buf, METH_VARARGS | METH_KEYWORDS,
|
||||
recvfrom_buf_doc},
|
||||
{"recvfrom_into", (PyCFunction)sock_recvfrom_into, METH_VARARGS | METH_KEYWORDS,
|
||||
recvfrom_into_doc},
|
||||
{"send", (PyCFunction)sock_send, METH_VARARGS,
|
||||
send_doc},
|
||||
{"sendall", (PyCFunction)sock_sendall, METH_VARARGS,
|
||||
|
|
Loading…
Reference in New Issue