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 }