0
0
mirror of https://github.com/zeromq/libzmq.git synced 2024-12-31 01:43:02 +08:00
libzmq/python/pyzmq.cpp

498 lines
15 KiB
C++
Raw Normal View History

2009-08-24 11:17:16 +02:00
/*
Copyright (c) 2007-2009 FastMQ Inc.
This file is part of 0MQ.
0MQ is free software; you can redistribute it and/or modify it under
the terms of the Lesser GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
0MQ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Lesser GNU General Public License for more details.
You should have received a copy of the Lesser GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
2009-09-02 10:22:23 +02:00
#include <stddef.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
2009-08-24 11:17:16 +02:00
#include <Python.h>
2009-09-08 14:54:04 +02:00
#include "../c/zmq.h"
2009-08-24 11:17:16 +02:00
2009-09-08 15:10:10 +02:00
#if defined _MSC_VER
#pragma warning (push)
#pragma warning (disable:4996)
#endif
2009-09-02 10:22:23 +02:00
struct context_t
2009-08-24 11:17:16 +02:00
{
PyObject_HEAD
2009-09-02 10:22:23 +02:00
void *handle;
2009-08-24 11:17:16 +02:00
};
2009-09-02 10:22:23 +02:00
PyObject *context_new (PyTypeObject *type, PyObject *args, PyObject *kwds)
2009-08-24 11:17:16 +02:00
{
2009-09-02 10:22:23 +02:00
context_t *self = (context_t*) type->tp_alloc (type, 0);
2009-08-24 11:17:16 +02:00
2009-09-02 10:22:23 +02:00
if (self)
self->handle = NULL;
2009-08-24 11:17:16 +02:00
return (PyObject*) self;
}
2009-09-02 10:22:23 +02:00
int context_init (context_t *self, PyObject *args, PyObject *kwdict)
2009-08-24 11:17:16 +02:00
{
int app_threads;
int io_threads;
2009-09-02 10:22:23 +02:00
static const char *kwlist [] = {"app_threads", "io_threads", NULL};
2009-08-24 11:17:16 +02:00
if (!PyArg_ParseTupleAndKeywords (args, kwdict, "ii", (char**) kwlist,
2009-09-02 10:22:23 +02:00
&app_threads, &io_threads)) {
PyErr_SetString (PyExc_SystemError, "invalid arguments");
return -1; // ?
2009-08-24 11:17:16 +02:00
}
2009-09-02 10:22:23 +02:00
assert (!self->handle);
self->handle = zmq_init (app_threads, io_threads);
if (!self->handle) {
PyErr_SetString (PyExc_SystemError, strerror (errno));
return -1; // ?
}
2009-08-24 11:17:16 +02:00
2009-09-02 10:22:23 +02:00
return 0;
2009-08-24 11:17:16 +02:00
}
2009-09-02 10:22:23 +02:00
void context_dealloc (context_t *self)
2009-08-24 11:17:16 +02:00
{
2009-09-02 10:22:23 +02:00
if (self->handle) {
int rc = zmq_term (self->handle);
if (rc != 0)
PyErr_SetString (PyExc_SystemError, strerror (errno));
}
2009-08-24 11:17:16 +02:00
2009-09-02 10:22:23 +02:00
self->ob_type->tp_free ((PyObject*) self);
2009-08-24 11:17:16 +02:00
}
2009-09-02 10:22:23 +02:00
struct socket_t
2009-08-24 11:17:16 +02:00
{
2009-09-02 10:22:23 +02:00
PyObject_HEAD
void *handle;
};
2009-08-24 11:17:16 +02:00
2009-09-02 10:22:23 +02:00
PyObject *socket_new (PyTypeObject *type, PyObject *args, PyObject *kwds)
2009-08-24 11:17:16 +02:00
{
2009-09-02 10:22:23 +02:00
socket_t *self = (socket_t*) type->tp_alloc (type, 0);
2009-08-24 11:17:16 +02:00
2009-09-02 10:22:23 +02:00
if (self)
self->handle = NULL;
2009-08-24 11:17:16 +02:00
2009-09-02 10:22:23 +02:00
return (PyObject*) self;
2009-08-24 11:17:16 +02:00
}
2009-09-02 10:22:23 +02:00
int socket_init (socket_t *self, PyObject *args, PyObject *kwdict)
2009-08-24 11:17:16 +02:00
{
2009-09-02 10:22:23 +02:00
context_t *context;
int socket_type;
2009-08-24 11:17:16 +02:00
static const char *kwlist [] = {"context", "type", NULL};
if (!PyArg_ParseTupleAndKeywords (args, kwdict, "Oi", (char**) kwlist,
2009-09-02 10:22:23 +02:00
&context, &socket_type)) {
PyErr_SetString (PyExc_SystemError, "invalid arguments");
return NULL;
}
// TODO: Check whether 'context' is really a libpyzmq.Context object.
2009-08-24 11:17:16 +02:00
2009-09-02 10:22:23 +02:00
assert (!self->handle);
self->handle = zmq_socket (context->handle, socket_type);
if (!self->handle) {
PyErr_SetString (PyExc_SystemError, strerror (errno));
return -1; // ?
2009-08-24 11:17:16 +02:00
}
2009-09-02 10:22:23 +02:00
return 0;
2009-08-24 11:17:16 +02:00
}
2009-09-02 10:22:23 +02:00
void socket_dealloc (socket_t *self)
2009-08-24 11:17:16 +02:00
{
2009-09-02 10:22:23 +02:00
if (self->handle) {
int rc = zmq_close (self->handle);
if (rc != 0)
PyErr_SetString (PyExc_SystemError, strerror (errno));
}
2009-08-24 11:17:16 +02:00
2009-09-02 10:22:23 +02:00
self->ob_type->tp_free ((PyObject*) self);
2009-08-24 11:17:16 +02:00
}
2009-09-02 10:22:23 +02:00
PyObject *socket_setsockopt (socket_t *self, PyObject *args, PyObject *kwdict)
2009-08-24 11:17:16 +02:00
{
int option;
PyObject* optval;
2009-09-02 10:22:23 +02:00
static const char *kwlist [] = {"option", "optval", NULL};
if (!PyArg_ParseTupleAndKeywords (args, kwdict, "iO", (char**) kwlist,
&option, &optval)) {
PyErr_SetString (PyExc_SystemError, "invalid arguments");
return NULL;
}
2009-08-24 11:17:16 +02:00
int rc;
2009-09-02 10:22:23 +02:00
if (PyInt_Check (optval)) {
int val = PyInt_AsLong (optval);
rc = zmq_setsockopt (self->handle, option, &val, sizeof (int));
}
2009-08-24 11:17:16 +02:00
if (PyString_Check (optval))
2009-09-02 10:22:23 +02:00
rc = zmq_setsockopt (self->handle, option, PyString_AsString (optval),
PyString_Size (optval));
else {
rc = -1;
errno = EINVAL;
}
2009-08-24 11:17:16 +02:00
2009-09-02 10:22:23 +02:00
if (rc != 0) {
PyErr_SetString (PyExc_SystemError, strerror (errno));
return NULL;
}
2009-08-24 11:17:16 +02:00
2009-09-02 10:22:23 +02:00
Py_INCREF (Py_None);
return Py_None;
2009-08-24 11:17:16 +02:00
}
2009-09-02 10:22:23 +02:00
PyObject *socket_bind (socket_t *self, PyObject *args, PyObject *kwdict)
2009-08-24 11:17:16 +02:00
{
2009-09-02 10:22:23 +02:00
char const *addr;
static const char *kwlist [] = {"addr", NULL};
if (!PyArg_ParseTupleAndKeywords (args, kwdict, "s", (char**) kwlist,
&addr)) {
PyErr_SetString (PyExc_SystemError, "invalid arguments");
return NULL;
2009-08-24 11:17:16 +02:00
}
2009-09-02 10:22:23 +02:00
int rc = zmq_bind (self->handle, addr);
if (rc != 0) {
PyErr_SetString (PyExc_SystemError, strerror (errno));
return NULL;
}
Py_INCREF (Py_None);
return Py_None;
2009-08-24 11:17:16 +02:00
}
2009-09-02 10:22:23 +02:00
PyObject *socket_connect (socket_t *self, PyObject *args, PyObject *kwdict)
2009-08-24 11:17:16 +02:00
{
2009-09-02 10:22:23 +02:00
char const *addr;
static const char *kwlist [] = {"addr", NULL};
if (!PyArg_ParseTupleAndKeywords (args, kwdict, "s", (char**) kwlist,
&addr)) {
PyErr_SetString (PyExc_SystemError, "invalid arguments");
return NULL;
}
int rc = zmq_connect (self->handle, addr);
if (rc != 0) {
PyErr_SetString (PyExc_SystemError, strerror (errno));
return NULL;
2009-08-24 11:17:16 +02:00
}
2009-09-02 10:22:23 +02:00
Py_INCREF (Py_None);
return Py_None;
2009-08-24 11:17:16 +02:00
}
2009-09-02 10:22:23 +02:00
PyObject *socket_send (socket_t *self, PyObject *args, PyObject *kwdict)
2009-08-24 11:17:16 +02:00
{
2009-09-02 10:22:23 +02:00
PyObject *msg; /* = PyString_FromStringAndSize (NULL, 0); */
int flags = 0;
static const char *kwlist [] = {"msg", "flags", NULL};
if (!PyArg_ParseTupleAndKeywords (args, kwdict, "S|i", (char**) kwlist,
&msg, &flags)) {
PyErr_SetString (PyExc_SystemError, "invalid arguments");
return NULL;
}
2009-08-24 11:17:16 +02:00
2009-09-02 10:22:23 +02:00
zmq_msg_t data;
int rc = zmq_msg_init_size (&data, PyString_Size (msg));
if (rc != 0) {
PyErr_SetString (PyExc_SystemError, strerror (errno));
return NULL;
}
memcpy (zmq_msg_data (&data), PyString_AsString (msg),
zmq_msg_size (&data));
rc = zmq_send (self->handle, &data, flags);
int rc2 = zmq_msg_close (&data);
assert (rc2 == 0);
if (rc != 0 && errno == EAGAIN)
return PyBool_FromLong (0);
if (rc != 0) {
PyErr_SetString (PyExc_SystemError, strerror (errno));
return NULL;
}
2009-08-24 11:17:16 +02:00
2009-09-02 10:22:23 +02:00
return PyBool_FromLong (1);
2009-08-24 11:17:16 +02:00
}
2009-09-02 10:22:23 +02:00
PyObject *socket_flush (socket_t *self, PyObject *args, PyObject *kwdict)
2009-08-24 11:17:16 +02:00
{
2009-09-02 10:22:23 +02:00
static const char *kwlist [] = {NULL};
if (!PyArg_ParseTupleAndKeywords (args, kwdict, "", (char**) kwlist)) {
PyErr_SetString (PyExc_SystemError, "invalid arguments");
return NULL;
}
int rc = zmq_flush (self->handle);
if (rc != 0) {
PyErr_SetString (PyExc_SystemError, strerror (errno));
return NULL;
}
Py_INCREF (Py_None);
return Py_None;
2009-08-24 11:17:16 +02:00
}
2009-09-02 10:22:23 +02:00
PyObject *socket_recv (socket_t *self, PyObject *args, PyObject *kwdict)
2009-08-24 11:17:16 +02:00
{
int flags = 0;
2009-09-02 10:22:23 +02:00
static const char *kwlist [] = {"flags", NULL};
if (!PyArg_ParseTupleAndKeywords (args, kwdict, "|i", (char**) kwlist,
&flags)) {
PyErr_SetString (PyExc_SystemError, "invalid arguments");
return NULL;
}
2009-08-24 11:17:16 +02:00
2009-09-02 10:22:23 +02:00
zmq_msg_t msg;
int rc = zmq_msg_init (&msg);
assert (rc == 0);
rc = zmq_recv (self->handle, &msg, flags);
if (rc != 0 && errno == EAGAIN) {
Py_INCREF (Py_None);
return Py_None;
}
if (rc != 0) {
PyErr_SetString (PyExc_SystemError, "invalid arguments");
return NULL;
}
PyObject *result = PyString_FromStringAndSize ((char*) zmq_msg_data (&msg),
zmq_msg_size (&msg));
rc = zmq_msg_close (&msg);
assert (rc == 0);
return result;
2009-08-24 11:17:16 +02:00
}
2009-09-02 10:22:23 +02:00
static PyMethodDef context_methods [] =
2009-08-24 11:17:16 +02:00
{
{
2009-09-02 10:22:23 +02:00
NULL
}
};
static PyTypeObject context_type =
{
PyObject_HEAD_INIT (NULL)
0,
"libpyzmq.Context", /* tp_name */
sizeof (context_t), /* tp_basicsize */
0, /* tp_itemsize */
(destructor) context_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
"", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
context_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc) context_init, /* tp_init */
0, /* tp_alloc */
2009-09-04 11:08:13 +02:00
context_new /* tp_new */
2009-09-02 10:22:23 +02:00
};
static PyMethodDef socket_methods [] =
{
2009-08-24 11:17:16 +02:00
{
"setsockopt",
2009-09-02 10:22:23 +02:00
(PyCFunction) socket_setsockopt,
2009-08-24 11:17:16 +02:00
METH_VARARGS | METH_KEYWORDS,
2009-09-02 10:22:23 +02:00
"setsockopt (option, optval) -> None\n\n"
2009-08-24 11:17:16 +02:00
},
{
"bind",
2009-09-02 10:22:23 +02:00
(PyCFunction) socket_bind,
2009-08-24 11:17:16 +02:00
METH_VARARGS | METH_KEYWORDS,
"bind (addr) -> None\n\n"
},
{
"connect",
2009-09-02 10:22:23 +02:00
(PyCFunction) socket_connect,
2009-08-24 11:17:16 +02:00
METH_VARARGS | METH_KEYWORDS,
"connect (addr) -> None\n\n"
},
{
2009-09-02 10:22:23 +02:00
"send",
(PyCFunction) socket_send,
2009-08-24 11:17:16 +02:00
METH_VARARGS | METH_KEYWORDS,
2009-09-02 10:22:23 +02:00
"send (msg, [flags]) -> Bool\n\n"
2009-08-24 11:17:16 +02:00
},
{
2009-09-02 10:22:23 +02:00
"flush",
(PyCFunction) socket_flush,
2009-08-24 11:17:16 +02:00
METH_VARARGS | METH_KEYWORDS,
2009-09-02 10:22:23 +02:00
"flush () -> None\n\n"
2009-08-24 11:17:16 +02:00
},
{
2009-09-02 10:22:23 +02:00
"recv",
(PyCFunction) socket_recv,
2009-08-24 11:17:16 +02:00
METH_VARARGS | METH_KEYWORDS,
2009-09-02 10:22:23 +02:00
"recv ([flags]) -> String\n\n"
2009-08-24 11:17:16 +02:00
},
{
NULL
}
};
2009-09-02 10:22:23 +02:00
static PyTypeObject socket_type =
2009-08-24 11:17:16 +02:00
{
PyObject_HEAD_INIT (NULL)
0,
2009-09-04 11:08:13 +02:00
"libpyzmq.Socket", /* tp_name */
2009-09-02 10:22:23 +02:00
sizeof (socket_t), /* tp_basicsize */
0, /* tp_itemsize */
(destructor) socket_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
"", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
socket_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc) socket_init, /* tp_init */
0, /* tp_alloc */
2009-09-04 11:08:13 +02:00
socket_new /* tp_new */
2009-08-24 11:17:16 +02:00
};
2009-09-02 10:22:23 +02:00
static PyMethodDef module_methods [] = {{ NULL, NULL, 0, NULL }};
static const char* libpyzmq_doc =
"Python API for 0MQ lightweight messaging kernel.\n"
"For more information see http://www.zeromq.org.\n"
"0MQ is distributed under GNU Lesser General Public License v3.\n";
2009-08-24 11:17:16 +02:00
#ifndef PyMODINIT_FUNC
#define PyMODINIT_FUNC void
#endif
2009-09-02 10:22:23 +02:00
PyMODINIT_FUNC initlibpyzmq ()
2009-08-24 11:17:16 +02:00
{
2009-09-04 11:08:13 +02:00
int rc = PyType_Ready (&context_type);
assert (rc == 0);
rc = PyType_Ready (&socket_type);
assert (rc == 0);
2009-08-24 11:17:16 +02:00
2009-09-02 10:22:23 +02:00
PyObject *module = Py_InitModule3 ("libpyzmq", module_methods,
libpyzmq_doc);
if (!module)
2009-08-24 11:17:16 +02:00
return;
2009-09-02 10:22:23 +02:00
Py_INCREF (&context_type);
PyModule_AddObject (module, "Context", (PyObject*) &context_type);
2009-09-04 11:08:13 +02:00
Py_INCREF (&socket_type);
2009-09-02 10:22:23 +02:00
PyModule_AddObject (module, "Socket", (PyObject*) &socket_type);
2009-08-24 11:17:16 +02:00
2009-09-02 10:22:23 +02:00
PyObject *dict = PyModule_GetDict (module);
assert (dict);
PyObject *t;
t = PyInt_FromLong (ZMQ_NOBLOCK);
PyDict_SetItemString (dict, "NOBLOCK", t);
2009-08-24 11:17:16 +02:00
Py_DECREF (t);
t = PyInt_FromLong (ZMQ_NOFLUSH);
2009-09-02 10:22:23 +02:00
PyDict_SetItemString (dict, "NOFLUSH", t);
2009-08-24 11:17:16 +02:00
Py_DECREF (t);
t = PyInt_FromLong (ZMQ_P2P);
2009-09-02 10:22:23 +02:00
PyDict_SetItemString (dict, "P2P", t);
2009-08-24 11:17:16 +02:00
Py_DECREF (t);
t = PyInt_FromLong (ZMQ_PUB);
2009-09-02 10:22:23 +02:00
PyDict_SetItemString (dict, "PUB", t);
2009-08-24 11:17:16 +02:00
Py_DECREF (t);
t = PyInt_FromLong (ZMQ_SUB);
2009-09-02 10:22:23 +02:00
PyDict_SetItemString (dict, "SUB", t);
2009-08-24 11:17:16 +02:00
Py_DECREF (t);
t = PyInt_FromLong (ZMQ_REQ);
2009-09-02 10:22:23 +02:00
PyDict_SetItemString (dict, "REQ", t);
2009-08-24 11:17:16 +02:00
Py_DECREF (t);
t = PyInt_FromLong (ZMQ_REP);
2009-09-02 10:22:23 +02:00
PyDict_SetItemString (dict, "REP", t);
2009-08-24 11:17:16 +02:00
Py_DECREF (t);
t = PyInt_FromLong (ZMQ_HWM);
2009-09-02 10:22:23 +02:00
PyDict_SetItemString (dict, "HWM", t);
2009-08-24 11:17:16 +02:00
Py_DECREF (t);
t = PyInt_FromLong (ZMQ_LWM);
2009-09-02 10:22:23 +02:00
PyDict_SetItemString (dict, "LWM", t);
Py_DECREF (t);
2009-08-24 11:17:16 +02:00
t = PyInt_FromLong (ZMQ_SWAP);
2009-09-02 10:22:23 +02:00
PyDict_SetItemString (dict, "SWAP", t);
2009-08-24 11:17:16 +02:00
Py_DECREF (t);
t = PyInt_FromLong (ZMQ_AFFINITY);
2009-09-02 10:22:23 +02:00
PyDict_SetItemString (dict, "AFFINITY", t);
2009-08-24 11:17:16 +02:00
Py_DECREF (t);
t = PyInt_FromLong (ZMQ_IDENTITY);
2009-09-02 10:22:23 +02:00
PyDict_SetItemString (dict, "IDENTITY", t);
Py_DECREF (t);
2009-08-24 11:17:16 +02:00
}
2009-09-08 15:10:10 +02:00
#if defined _MSC_VER
#pragma warning (pop)
#endif