00001
#include "Python.h"
00002
#include <qstring.h>
00003
#include <qdatastream.h>
00004
#include <dcopclient.h>
00005
#include <dcopobject.h>
00006
00007
00008 static PyObject *
pydcopc_marshal_QString(PyObject *, PyObject *arg)
00009 {
00010
QString str;
00011
char *p;
00012 Py_UNICODE *ustr;
int ulen;
00013
00014
if (PyArg_ParseTuple(arg, (
char*)
"s", &p)) {
00015 str = QString::fromLatin1(p);
00016 }
else if (PyArg_ParseTuple(arg, (
char*)
"u#", &ustr, &ulen)) {
00017 str =
QString((
const QChar*)ustr, (uint)ulen);
00018 }
else {
00019 PyErr_SetString(PyExc_TypeError,
"Expected string or unicode string");
00020
return 0;
00021 }
00022
00023
QByteArray data;
00024
QDataStream stream(data, IO_WriteOnly);
00025 stream << str;
00026
00027
return Py_BuildValue((
char*)
"s#", data.data(), data.size());
00028 }
00029
00030
00031 static PyObject *
pydcopc_marshal_QCString(PyObject *, PyObject *arg)
00032 {
00033
QCString cstr;
00034
00035
char *p;
00036 Py_UNICODE *ustr;
int ulen;
00037
00038
if (PyArg_ParseTuple(arg, (
char*)
"s", &p)) {
00039 cstr =
QCString(p);
00040 }
else if (PyArg_ParseTuple(arg, (
char*)
"u#", &ustr, &ulen)) {
00041 cstr =
QString((
const QChar*)ustr, (uint)ulen).local8Bit();
00042 }
else {
00043 PyErr_SetString(PyExc_TypeError,
"Expected string or unicode string");
00044
return 0;
00045 }
00046
00047
QByteArray data;
00048
QDataStream stream(data, IO_WriteOnly);
00049 stream << cstr;
00050
00051
return Py_BuildValue((
char*)
"s#", data.data(), data.size());
00052 }
00053
00054
00055 static PyObject *
pydcopc_marshal_int8(PyObject *, PyObject *arg)
00056 {
00057
int n;
00058
if (!PyArg_ParseTuple(arg, (
char*)
"i", &n))
00059
return 0;
00060
00061
QByteArray data;
00062
QDataStream stream(data, IO_WriteOnly);
00063 stream << (Q_INT8) n;
00064
00065
return Py_BuildValue((
char*)
"s#", data.data(), data.size());
00066 }
00067
00068
00069 static PyObject *
pydcopc_marshal_int16(PyObject *, PyObject *arg)
00070 {
00071
int n;
00072
if (!PyArg_ParseTuple(arg, (
char*)
"i", &n))
00073
return 0;
00074
00075
QByteArray data;
00076
QDataStream stream(data, IO_WriteOnly);
00077 stream << (Q_INT16)n;
00078
00079
return Py_BuildValue((
char*)
"s#", data.data(), data.size());
00080 }
00081
00082
00083 static PyObject *
pydcopc_marshal_int32(PyObject *, PyObject *arg)
00084 {
00085
long n;
00086
if (!PyArg_ParseTuple(arg, (
char*)
"l", &n))
00087
return 0;
00088
00089
QByteArray data;
00090
QDataStream stream(data, IO_WriteOnly);
00091 stream << (Q_INT32)n;
00092
00093
return Py_BuildValue((
char*)
"s#", data.data(), data.size());
00094 }
00095
00096
00097
00098 static PyObject *
pydcopc_marshal_int(PyObject *, PyObject *arg)
00099 {
00100
long n;
00101
if (!PyArg_ParseTuple(arg, (
char*)
"l", &n))
00102
return 0;
00103
00104
QByteArray data;
00105
QDataStream stream(data, IO_WriteOnly);
00106 stream << (
int)n;
00107
00108
return Py_BuildValue((
char*)
"s#", data.data(), data.size());
00109 }
00110
00111
00112 static PyObject *
pydcopc_marshal_uint8(PyObject *, PyObject *arg)
00113 {
00114
int n;
00115
if (!PyArg_ParseTuple(arg, (
char*)
"i", &n))
00116
return 0;
00117
00118
QByteArray data;
00119
QDataStream stream(data, IO_WriteOnly);
00120 stream << (Q_INT8)n;
00121
00122
return Py_BuildValue((
char*)
"s#", data.data(), data.size());
00123 }
00124
00125
00126 static PyObject *
pydcopc_marshal_uint16(PyObject *, PyObject *arg)
00127 {
00128
int n;
00129
if (!PyArg_ParseTuple(arg, (
char*)
"i", &n))
00130
return 0;
00131
00132
QByteArray data;
00133
QDataStream stream(data, IO_WriteOnly);
00134 stream << (Q_UINT16)n;
00135
00136
return Py_BuildValue((
char*)
"s#", data.data(), data.size());
00137 }
00138
00139
00140 static PyObject *
pydcopc_marshal_uint32(PyObject *, PyObject *arg)
00141 {
00142
long n;
00143
if (!PyArg_ParseTuple(arg, (
char*)
"l", &n))
00144
return 0;
00145
00146
QByteArray data;
00147
QDataStream stream(data, IO_WriteOnly);
00148 stream << (Q_UINT32)n;
00149
00150
return Py_BuildValue((
char*)
"s#", data.data(), data.size());
00151 }
00152
00153
00154 static PyObject *
pydcopc_marshal_uint(PyObject *, PyObject *arg)
00155 {
00156
long n;
00157
if (!PyArg_ParseTuple(arg, (
char*)
"l", &n))
00158
return 0;
00159
00160
QByteArray data;
00161
QDataStream stream(data, IO_WriteOnly);
00162 stream << (uint)n;
00163
00164
return Py_BuildValue((
char*)
"s#", data.data(), data.size());
00165 }
00166
00167
00168 static PyObject *
pydcopc_marshal_float(PyObject *, PyObject *arg)
00169 {
00170
double x;
00171
if (!PyArg_ParseTuple(arg, (
char*)
"d", &x))
00172
return 0;
00173
00174
QByteArray data;
00175
QDataStream stream(data, IO_WriteOnly);
00176 stream << (
float)x;
00177
00178
return Py_BuildValue((
char*)
"s#", data.data(), data.size());
00179 }
00180
00181
00182 static PyObject *
pydcopc_marshal_double(PyObject *, PyObject *arg)
00183 {
00184
double x;
00185
if (!PyArg_ParseTuple(arg, (
char*)
"d", &x))
00186
return 0;
00187
00188
QByteArray data;
00189
QDataStream stream(data, IO_WriteOnly);
00190 stream << (
double)x;
00191
00192
return Py_BuildValue((
char*)
"s#", data.data(), data.size());
00193 }
00194
00195
00196 static PyObject *
pydcopc_demarshal_QString(PyObject *, PyObject *arg)
00197 {
00198
char *datastr;
int datalen;
00199
if (!PyArg_ParseTuple(arg, (
char*)
"s#", &datastr, &datalen))
00200
return 0;
00201
00202
QByteArray data; data.duplicate(datastr, datalen);
00203
QDataStream stream(data, IO_ReadOnly);
00204
QString str;
00205 stream >> str;
00206
int advance = stream.device()->at();
00207
00208
00209
00210
00211 Py_UNICODE *p =
new Py_UNICODE[str.length()];
00212
for (
int i=0; i < (
int)str.length(); ++i)
00213 p[i] = str.at(i).unicode();
00214 PyObject *obj = Py_BuildValue((
char*)
"(u#s#)", p, str.length(), data.data()+advance, data.size()-advance);
00215
delete p;
00216
return obj;
00217 }
00218
00219
00220 static PyObject *
pydcopc_demarshal_QCString(PyObject *, PyObject *arg)
00221 {
00222
char *datastr;
int datalen;
00223
if (!PyArg_ParseTuple(arg, (
char*)
"s#", &datastr, &datalen))
00224
return 0;
00225
00226
QByteArray data; data.duplicate(datastr, datalen);
00227
QDataStream stream(data, IO_ReadOnly);
00228
QCString str;
00229 stream >> str;
00230
int advance = stream.device()->at();
00231
00232
return Py_BuildValue((
char*)
"(ss#)", str.data(), data.data()+advance, data.size()-advance);
00233 }
00234
00235
00236 static PyObject *
pydcopc_demarshal_int8(PyObject *, PyObject *arg)
00237 {
00238
char *datastr;
int datalen;
00239
if (!PyArg_ParseTuple(arg, (
char*)
"s#", &datastr, &datalen))
00240
return 0;
00241
00242
QByteArray data; data.duplicate(datastr, datalen);
00243
QDataStream stream(data, IO_ReadOnly);
00244 Q_INT8 n;
00245 stream >> n;
00246
int advance = stream.device()->at();
00247
00248
return Py_BuildValue((
char*)
"(is#)", n, data.data()+advance, data.size()-advance);
00249 }
00250
00251
00252 static PyObject *
pydcopc_demarshal_int16(PyObject *, PyObject *arg)
00253 {
00254
char *datastr;
int datalen;
00255
if (!PyArg_ParseTuple(arg, (
char*)
"s#", &datastr, &datalen))
00256
return 0;
00257
00258
QByteArray data; data.duplicate(datastr, datalen);
00259
QDataStream stream(data, IO_ReadOnly);
00260 Q_INT16 n;
00261 stream >> n;
00262
int advance = stream.device()->at();
00263
00264
return Py_BuildValue((
char*)
"(is#)", n, data.data()+advance, data.size()-advance);
00265 }
00266
00267
00268 static PyObject *
pydcopc_demarshal_int32(PyObject *, PyObject *arg)
00269 {
00270
char *datastr;
int datalen;
00271
if (!PyArg_ParseTuple(arg, (
char*)
"s#", &datastr, &datalen))
00272
return 0;
00273
00274
QByteArray data; data.duplicate(datastr, datalen);
00275
QDataStream stream(data, IO_ReadOnly);
00276 Q_INT32 n;
00277 stream >> n;
00278
int advance = stream.device()->at();
00279
00280
return Py_BuildValue((
char*)
"(ls#)", (
long)n, data.data()+advance, data.size()-advance);
00281 }
00282
00283
00284 static PyObject *
pydcopc_demarshal_int(PyObject *, PyObject *arg)
00285 {
00286
char *datastr;
int datalen;
00287
if (!PyArg_ParseTuple(arg, (
char*)
"s#", &datastr, &datalen))
00288
return 0;
00289
00290
QByteArray data; data.duplicate(datastr, datalen);
00291
QDataStream stream(data, IO_ReadOnly);
00292 uint n;
00293 stream >> n;
00294
int advance = stream.device()->at();
00295
00296
return Py_BuildValue((
char*)
"(ls#)", (
long)n, data.data()+advance, data.size()-advance);
00297 }
00298
00299
00300 static PyObject *
pydcopc_demarshal_uint8(PyObject *, PyObject *arg)
00301 {
00302
char *datastr;
int datalen;
00303
if (!PyArg_ParseTuple(arg, (
char*)
"s#", &datastr, &datalen))
00304
return 0;
00305
00306
QByteArray data; data.duplicate(datastr, datalen);
00307
QDataStream stream(data, IO_ReadOnly);
00308 Q_UINT8 n;
00309 stream >> n;
00310
int advance = stream.device()->at();
00311
00312
return Py_BuildValue((
char*)
"(is#)", n, data.data()+advance, data.size()-advance);
00313 }
00314
00315
00316 static PyObject *
pydcopc_demarshal_uint16(PyObject *, PyObject *arg)
00317 {
00318
char *datastr;
int datalen;
00319
if (!PyArg_ParseTuple(arg, (
char*)
"s#", &datastr, &datalen))
00320
return 0;
00321
00322
QByteArray data; data.duplicate(datastr, datalen);
00323
QDataStream stream(data, IO_ReadOnly);
00324 Q_UINT16 n;
00325 stream >> n;
00326
int advance = stream.device()->at();
00327
00328
return Py_BuildValue((
char*)
"(is#)", n, data.data()+advance, data.size()-advance);
00329 }
00330
00331
00332 static PyObject *
pydcopc_demarshal_uint32(PyObject *, PyObject *arg)
00333 {
00334
char *datastr;
int datalen;
00335
if (!PyArg_ParseTuple(arg, (
char*)
"s#", &datastr, &datalen))
00336
return 0;
00337
00338
QByteArray data; data.duplicate(datastr, datalen);
00339
QDataStream stream(data, IO_ReadOnly);
00340 Q_UINT32 n;
00341 stream >> n;
00342
int advance = stream.device()->at();
00343
00344
return Py_BuildValue((
char*)
"(ls#)", (
long)n, data.data()+advance, data.size()-advance);
00345 }
00346
00347
00348 static PyObject *
pydcopc_demarshal_uint(PyObject *, PyObject *arg)
00349 {
00350
char *datastr;
int datalen;
00351
if (!PyArg_ParseTuple(arg, (
char*)
"s#", &datastr, &datalen))
00352
return 0;
00353
00354
QByteArray data; data.duplicate(datastr, datalen);
00355
QDataStream stream(data, IO_ReadOnly);
00356 uint n;
00357 stream >> n;
00358
int advance = stream.device()->at();
00359
00360
return Py_BuildValue((
char*)
"(ls#)", (
long)n, data.data()+advance, data.size()-advance);
00361 }
00362
00363
00364 static PyObject *
pydcopc_demarshal_float(PyObject *, PyObject *arg)
00365 {
00366
char *datastr;
int datalen;
00367
if (!PyArg_ParseTuple(arg, (
char*)
"s#", &datastr, &datalen))
00368
return 0;
00369
00370
QByteArray data; data.duplicate(datastr, datalen);
00371
QDataStream stream(data, IO_ReadOnly);
00372
float x;
00373 stream >> x;
00374
int advance = stream.device()->at();
00375
00376
return Py_BuildValue((
char*)
"(ds#)", (
double)x, data.data()+advance, data.size()-advance);
00377 }
00378
00379
00380 static PyObject *
pydcopc_demarshal_double(PyObject *, PyObject *arg)
00381 {
00382
char *datastr;
int datalen;
00383
if (!PyArg_ParseTuple(arg, (
char*)
"s#", &datastr, &datalen))
00384
return 0;
00385
00386
QByteArray data; data.duplicate(datastr, datalen);
00387
QDataStream stream(data, IO_ReadOnly);
00388
double x;
00389 stream >> x;
00390
int advance = stream.device()->at();
00391
00392
return Py_BuildValue((
char*)
"(ds#)", x, data.data()+advance, data.size()-advance);
00393 }
00394
00395
00396 DCOPClient *
pydcopc_client = 0;
00397
00398 static DCOPClient *
dcopClient()
00399 {
00400
if (!
DCOPClient::mainClient()) {
00401 qDebug(
"Creating dcop client");
00402
pydcopc_client =
new DCOPClient;
00403
if (!
pydcopc_client->
attach()) {
00404 PyErr_SetString(PyExc_RuntimeError,
"DCOP: could not attach");
00405
return NULL;
00406 }
00407 }
00408
return DCOPClient::mainClient();
00409 }
00410
00411
00412
00413 static PyObject *
pydcopc_call( PyObject *, PyObject *args )
00414 {
00415
char *cappname;
00416
char *cobjname;
00417
char *csignature;
00418
char *datastr;
00419
int datalen;
00420
00421
if (!PyArg_ParseTuple(args, (
char*)
"ssss#", &cappname, &cobjname, &csignature, &datastr, &datalen))
00422
return NULL;
00423
00424
QCString appname(cappname);
00425
QCString objname(cobjname);
00426
QCString signature(csignature);
00427
QByteArray data; data.duplicate(datastr, datalen);
00428
00429
DCOPClient *client =
dcopClient();
00430 qDebug(
"Calling %s %s %s with datalen %d", appname.data(), objname.data(), signature.data(), data.size() );
00431
00432
QCString replyType;
00433
QByteArray replyData;
00434
if (!client->
call(appname, objname, signature, data, replyType, replyData)) {
00435 PyErr_SetString(PyExc_RuntimeError,
"DCOP: call failed");
00436
return NULL;
00437 }
00438
00439
return Py_BuildValue((
char*)
"(ss#)", replyType.data(), replyData.data(), replyData.size());
00440 }
00441
00442
00443
00444 static PyObject *
pydcopc_send( PyObject *, PyObject *args )
00445 {
00446
char *cappname;
00447
char *cobjname;
00448
char *csignature;
00449
char *datastr;
00450
int datalen;
00451
00452
if (!PyArg_ParseTuple(args, (
char*)
"ssss#", &cappname, &cobjname, &csignature, &datastr, &datalen))
00453
return NULL;
00454
00455
QCString appname(cappname);
00456
QCString objname(cobjname);
00457
QCString signature(csignature);
00458
QByteArray data; data.duplicate(datastr, datalen);
00459
00460
DCOPClient *client =
dcopClient();
00461
if (!client->
send(appname, objname, signature, data)) {
00462 PyErr_SetString(PyExc_RuntimeError,
"DCOP: send failed");
00463
return NULL;
00464 }
00465
00466 Py_INCREF(Py_None);
00467
return Py_None;
00468 }
00469
00470
00471 class PyDCOP_Dispatcher :
public DCOPObject
00472 {
00473
public:
00474 PyDCOP_Dispatcher()
00475 :
DCOPObject("
PyDCOP_Dispatcher"),
no(0)
00476 {}
00477 void connectToPython(
QCString appname,
QCString objname,
00478
QCString signal, PyObject *func)
00479 {
00480
QCString slot;
00481 slot.setNum(++
no);
00482 slot.prepend(
"f");
00483 slot.append(
"()");
00484
receivers[slot] = func;
00485 Py_INCREF(func);
00486
bool res = connectDCOPSignal(appname, objname, signal, slot,
false);
00487 qDebug(
"PyDCOP connect %s/%s/%s/%s has result %s",
00488 appname.data(), objname.data(),
00489 signal.data(), slot.data(),
00490 (res?
"true" :
"false"));
00491 }
00492 virtual bool process(
const QCString &fun,
const QByteArray &data,
00493
QCString& replyType,
QByteArray &replyData)
00494 {
00495 qDebug(
"fun: %s", fun.data());
00496
QMap<QCString,PyObject*>::Iterator it =
receivers.find(fun);
00497
if (it !=
receivers.end()) {
00498 Py_INCREF(Py_None);
00499 PyObject *arglist = Py_BuildValue((
char*)
"()");
00500 PyEval_CallObject(*it, arglist);
00501
return true;
00502 }
00503
return DCOPObject::process(fun, data, replyType, replyData);
00504 }
00505
private:
00506 int no;
00507 QMap<QCString,PyObject*> receivers;
00508 };
00509
00510
00511 DCOPObject *
pydcopc_dispatcher = 0;
00512
00513 static PyDCOP_Dispatcher *
signalDispatcher()
00514 {
00515
if (!
pydcopc_dispatcher)
00516
pydcopc_dispatcher =
new PyDCOP_Dispatcher();
00517
return static_cast<PyDCOP_Dispatcher*>(
pydcopc_dispatcher);
00518 }
00519
00520
00521
00522 static PyObject *
pydcopc_connect( PyObject *, PyObject *args )
00523 {
00524
char *appname, *objname, *signal;
00525 PyObject *func;
00526
00527
if (!PyArg_ParseTuple(args, (
char*)
"sssO", &appname, &objname, &signal, &func))
00528
return 0;
00529
00530 qDebug(
"Connecting %s/%s/%s", appname, objname, signal);
00531
signalDispatcher()->
connectToPython(appname, objname, signal, func);
00532
00533 Py_INCREF(Py_None);
00534
return Py_None;
00535 }
00536
00537
00538 static PyMethodDef
pydcopc_methods[] = {
00539 { (
char*)
"call",
pydcopc_call, METH_VARARGS, NULL },
00540 { (
char*)
"send",
pydcopc_send, METH_VARARGS, NULL },
00541 { (
char*)
"connect",
pydcopc_connect, METH_VARARGS, NULL },
00542 { (
char*)
"marshal_QString",
pydcopc_marshal_QString, METH_VARARGS, NULL },
00543 { (
char*)
"marshal_QCString",
pydcopc_marshal_QCString, METH_VARARGS, NULL },
00544 { (
char*)
"marshal_int8",
pydcopc_marshal_int8, METH_VARARGS, NULL },
00545 { (
char*)
"marshal_int16",
pydcopc_marshal_int16, METH_VARARGS, NULL },
00546 { (
char*)
"marshal_int32",
pydcopc_marshal_int32, METH_VARARGS, NULL },
00547 { (
char*)
"marshal_int",
pydcopc_marshal_int, METH_VARARGS, NULL },
00548 { (
char*)
"marshal_uint8",
pydcopc_marshal_uint8, METH_VARARGS, NULL },
00549 { (
char*)
"marshal_uint16",
pydcopc_marshal_uint16, METH_VARARGS, NULL },
00550 { (
char*)
"marshal_uint32",
pydcopc_marshal_uint32, METH_VARARGS, NULL },
00551 { (
char*)
"marshal_uint",
pydcopc_marshal_uint, METH_VARARGS, NULL },
00552 { (
char*)
"marshal_float",
pydcopc_marshal_float, METH_VARARGS, NULL },
00553 { (
char*)
"marshal_double",
pydcopc_marshal_double, METH_VARARGS, NULL },
00554 { (
char*)
"demarshal_QString",
pydcopc_demarshal_QString, METH_VARARGS, NULL },
00555 { (
char*)
"demarshal_QCString",
pydcopc_demarshal_QCString, METH_VARARGS, NULL },
00556 { (
char*)
"demarshal_int8",
pydcopc_demarshal_int8, METH_VARARGS, NULL },
00557 { (
char*)
"demarshal_int16",
pydcopc_demarshal_int16, METH_VARARGS, NULL },
00558 { (
char*)
"demarshal_int32",
pydcopc_demarshal_int32, METH_VARARGS, NULL },
00559 { (
char*)
"demarshal_int",
pydcopc_demarshal_int, METH_VARARGS, NULL },
00560 { (
char*)
"demarshal_uint8",
pydcopc_demarshal_uint8, METH_VARARGS, NULL },
00561 { (
char*)
"demarshal_uint16",
pydcopc_demarshal_uint16, METH_VARARGS, NULL },
00562 { (
char*)
"demarshal_uint32",
pydcopc_demarshal_uint32, METH_VARARGS, NULL },
00563 { (
char*)
"demarshal_uint",
pydcopc_demarshal_uint, METH_VARARGS, NULL },
00564 { (
char*)
"demarshal_float",
pydcopc_demarshal_float, METH_VARARGS, NULL },
00565 { (
char*)
"demarshal_double",
pydcopc_demarshal_double, METH_VARARGS, NULL },
00566 { NULL, NULL, 0, NULL }
00567 };
00568
00569
extern "C"
00570 {
00571 void initpydcopc()
00572 {
00573 (
void) Py_InitModule((
char*)
"pydcopc",
pydcopc_methods);
00574 }
00575 }