00001
00002 #include "BnPython.h"
00003
00004
00005 static PyObject* Print (PyObject *self, PyObject *args)
00006 {
00007 BnPython* myObj = BnPython::GetPointer (PyInt_AsLong (self));
00008 if (!myObj) return NULL;
00009
00010 PyObject *itr = PyObject_GetIter(args);
00011 if (itr == NULL) return NULL;
00012 PyObject *item, *str;
00013 const char* ps;
00014 while (item = PyIter_Next(itr))
00015 {
00016 if (str = PyObject_Str (item))
00017 if (ps = PyString_AsString (str))
00018 myObj->sBuffer += ps;
00019 Py_DECREF(str);
00020 Py_DECREF(item);
00021 }
00022 Py_DECREF(itr);
00023 if (!myObj->CheckSizeLimit ())
00024 return NULL;
00025 Py_RETURN_NONE;
00026 }
00027
00028
00029
00030
00031
00032 static PyObject* GetRequestHeader (PyObject *self, PyObject *args)
00033 {
00034 BnPython* myObj = BnPython::GetPointer (PyInt_AsLong (self));
00035 if (!myObj) return NULL;
00036 const char* name;
00037 if (!PyArg_ParseTuple(args, "s", &name))
00038 return NULL;
00039 BufferHolder result = myObj->pReq->GetRequestHeader (BufferHolder (name));
00040 return Py_BuildValue("s", result.pointer);
00041 }
00042
00043 static PyObject* GetRequestVariable (PyObject *self, PyObject *args)
00044 {
00045 BnPython* myObj = BnPython::GetPointer (PyInt_AsLong (self));
00046 if (!myObj) return NULL;
00047 const char* name;
00048 if (!PyArg_ParseTuple(args, "s", &name))
00049 return NULL;
00050 BufferHolder result = myObj->pReq->GetRequestVariable (BufferHolder (name));
00051 return Py_BuildValue("s", result.pointer);
00052 }
00053
00054 static PyObject* SetRequestVariable (PyObject *self, PyObject *args)
00055 {
00056 BnPython* myObj = BnPython::GetPointer (PyInt_AsLong (self));
00057 if (!myObj) return NULL;
00058 const char* name;
00059 const char* value;
00060 if (!PyArg_ParseTuple(args, "ss", &name, &value))
00061 return NULL;
00062 myObj->pReq->SetRequestVariable (BufferHolder (name), BufferHolder (value));
00063 Py_RETURN_NONE;
00064 }
00065
00066 static PyObject* GetRequestVarsNamesList (PyObject *self, PyObject *args)
00067 {
00068 BnPython* myObj = BnPython::GetPointer (PyInt_AsLong (self));
00069 if (!myObj) return NULL;
00070 const char* sep;
00071 if (!PyArg_ParseTuple(args, "s", &sep))
00072 return NULL;
00073 BufferHolder result = myObj->pReq->GetRequestVarsNamesList (BufferHolder (sep));
00074 return Py_BuildValue("s", result.pointer);
00075 }
00076
00077 static PyObject* SetResponseHeader (PyObject *self, PyObject *args)
00078 {
00079 BnPython* myObj = BnPython::GetPointer (PyInt_AsLong (self));
00080 if (!myObj) return NULL;
00081 const char* name;
00082 const char* value;
00083 if (!PyArg_ParseTuple(args, "ss", &name, &value))
00084 return NULL;
00085 myObj->pRes->SetResponseHeader (BufferHolder (name), BufferHolder (value));
00086 Py_RETURN_NONE;
00087 }
00088
00089 static PyObject* SetResponseCookie (PyObject *self, PyObject *args)
00090 {
00091 BnPython* myObj = BnPython::GetPointer (PyInt_AsLong (self));
00092 if (!myObj) return NULL;
00093 const char* name;
00094 const char* value;
00095 int days = 1;
00096 const char* path = NULL;
00097 if (!PyArg_ParseTuple(args, "ss|is", &name, &value, &days, &path))
00098 return NULL;
00099 if (path)
00100 myObj->pRes->SetResponseCookie (BufferHolder (name), BufferHolder (value),
00101 days, BufferHolder (path));
00102 else
00103 myObj->pRes->SetResponseCookie (BufferHolder (name), BufferHolder (value), days);
00104 Py_RETURN_NONE;
00105 }
00106
00107 static PyObject* Clear (PyObject *self, PyObject *args)
00108 {
00109 BnPython* myObj = BnPython::GetPointer (PyInt_AsLong (self));
00110 if (!myObj) return NULL;
00111 myObj->pRes->Clear ();
00112 myObj->sBuffer.clear ();
00113 Py_RETURN_NONE;
00114 }
00115
00116 static PyObject* Flush (PyObject *self, PyObject *args)
00117 {
00118 BnPython* myObj = BnPython::GetPointer (PyInt_AsLong (self));
00119 if (!myObj) return NULL;
00120 try
00121 {
00122 myObj->pRes->Flush (BufferHolder (myObj->sBuffer.c_str (),
00123 myObj->sBuffer. size ()));
00124 }
00125 catch (int e)
00126 {
00127
00128 myObj->nException = e;
00129 PyErr_SetString(PyExc_SystemError, "Connection closed");
00130 return NULL;
00131 }
00132 myObj->sBuffer.clear ();
00133 Py_RETURN_NONE;
00134 }
00135
00136 static PyObject* GetAdapter (PyObject *self, PyObject *args)
00137 {
00138 BnPython* myObj = BnPython::GetPointer (PyInt_AsLong (self));
00139 if (!myObj) return NULL;
00140 const char* name;
00141 if (!PyArg_ParseTuple(args, "s", &name))
00142 return NULL;
00143 unsigned int aid = 0;
00144 if (myObj->pSet)
00145 aid = myObj->pSet->GetAdapter (BufferHolder (name));
00146 if (aid > 0)
00147 myObj->oAdaptersList.insert (aid);
00148 return Py_BuildValue("i", aid);
00149 }
00150
00151 static PyObject* ReleaseAdapter (PyObject *self, PyObject *args)
00152 {
00153 BnPython* myObj = BnPython::GetPointer (PyInt_AsLong (self));
00154 if (!myObj) return NULL;
00155 unsigned int aid;
00156 if (!PyArg_ParseTuple(args, "i", &aid))
00157 return NULL;
00158 if (myObj->pSet)
00159 {
00160 myObj->pSet->ReleaseAdapter (aid);
00161 myObj->oAdaptersList.erase (aid);
00162 }
00163 Py_RETURN_NONE;
00164 }
00165
00166 static PyObject* Read (PyObject *self, PyObject *args)
00167 {
00168 BnPython* myObj = BnPython::GetPointer (PyInt_AsLong (self));
00169 if (!myObj) return NULL;
00170 unsigned int aid;
00171 const char* address;
00172 if (!PyArg_ParseTuple(args, "is", &aid, &address))
00173 return NULL;
00174 BufferHolder result ("");
00175 try
00176 {
00177 if (myObj->pSet)
00178 result = myObj->pSet->Read (aid, BufferHolder (address));
00179 }
00180 catch (BufferHolder e)
00181 {
00182 char tmp [100] = {0};
00183 strncpy (tmp, e.pointer, e.size < 100 ? e.size : 99);
00184 PyErr_SetString(PyExc_SystemError, tmp);
00185 return NULL;
00186 }
00187 return Py_BuildValue("s", result.pointer);
00188 }
00189
00190 static PyObject* Write (PyObject *self, PyObject *args)
00191 {
00192 BnPython* myObj = BnPython::GetPointer (PyInt_AsLong (self));
00193 if (!myObj) return NULL;
00194 unsigned int aid;
00195 const char* address;
00196 const char* value = NULL;
00197 if (!PyArg_ParseTuple(args, "is|s", &aid, &address, &value))
00198 return NULL;
00199 bool result = false;
00200 try
00201 {
00202 if (myObj->pSet)
00203 result = myObj->pSet->Write (aid, BufferHolder (address),
00204 BufferHolder (value));
00205 }
00206 catch (BufferHolder e)
00207 {
00208 char tmp [100] = {0};
00209 strncpy (tmp, e.pointer, e.size < 100 ? e.size : 99);
00210 PyErr_SetString(PyExc_SystemError, tmp);
00211 return NULL;
00212 }
00213 return Py_BuildValue("b", result);
00214 }
00215
00216 static PyObject* Exit (PyObject *self, PyObject *args)
00217 {
00218 BnPython* myObj = BnPython::GetPointer (PyInt_AsLong (self));
00219 if (!myObj) return NULL;
00220 myObj->bExit = true;
00221 return NULL;
00222 }
00223
00224
00225 static PyMethodDef EmbMethods[] =
00226 {
00227 {"bn_print", Print, METH_VARARGS, "Print string to Beesnest buffer"},
00228 {"bn_get_hdr", GetRequestHeader, METH_VARARGS, "Return a HTTP request header"},
00229 {"bn_get_var", GetRequestVariable, METH_VARARGS, "Return a HTTP request variable"},
00230 {"bn_set_var", SetRequestVariable, METH_VARARGS, "Set a HTTP request variable"},
00231 {"bn_get_vars", GetRequestVarsNamesList, METH_VARARGS, "Return all HTTP request variables"},
00232 {"bn_set_hdr", SetResponseHeader, METH_VARARGS, "Set HTTP response header"},
00233 {"bn_set_cookie", SetResponseCookie, METH_VARARGS, "Set HTTP response cookie"},
00234 {"bn_clear", Clear, METH_VARARGS, "Clear the response"},
00235 {"bn_flush", Flush, METH_VARARGS, "Flush the response"},
00236 {"bn_adapter", GetAdapter, METH_VARARGS, "Get an adapter ID by name"},
00237 {"bn_free", ReleaseAdapter, METH_VARARGS, "Release an adapter by ID"},
00238 {"bn_read", Read, METH_VARARGS, "Read from adapter"},
00239 {"bn_write", Write, METH_VARARGS, "Write to adapter"},
00240 {"exit", Exit, METH_VARARGS, "Terminate the script"},
00241 {NULL, NULL, 0, NULL}
00242 };
00243
00244
00245
00246
00247 int BnPython::counter = 0;
00248 map<int, BnPython*> BnPython::mPointers;
00249
00250
00251
00252
00253
00254
00255 BnPython* BnPython::GetPointer (int num)
00256 {
00257 map<int, BnPython*>::const_iterator itr = mPointers.find (num);
00258 if (itr == mPointers.end ())
00259 {
00260 PyErr_SetString(PyExc_ValueError,
00261 "First argument to bn_XXX function is not valid");
00262 return NULL;
00263 }
00264 return (itr->second);
00265 }
00266
00267 BnPython::BnPython (const char* name, bool (*pGetParam)(const char*, char*, int))
00268 :pRes (NULL), pReq (NULL), pSet (NULL), nException (0)
00269 {
00270 sName = name;
00271 pfGetParam = pGetParam;
00272 nPointerCell = ++counter;
00273 mPointers[nPointerCell] = this;
00274
00275 PyEval_AcquireLock();
00276 oTS = Py_NewInterpreter();
00277
00278
00279
00280 Py_InitModule4("BnPython", EmbMethods, "Beesnest-Python Functions",
00281 Py_BuildValue ("i", nPointerCell), PYTHON_API_VERSION);
00282
00283 PyRun_SimpleString("import sys\nimport cStringIO");
00284 PyRun_SimpleString("from BnPython import *");
00285
00286 PyThreadState_Swap(NULL);
00287 PyEval_ReleaseLock();
00288 }
00289
00290
00291 BnPython::~BnPython ()
00292 {
00293 Stored ();
00294 mPointers.erase (nPointerCell);
00295
00296 PyEval_AcquireLock();
00297 PyThreadState_Swap(oTS);
00298 Py_EndInterpreter(oTS);
00299 PyEval_ReleaseLock();
00300 }
00301
00302 void BnPython::Stored ()
00303 {
00304 ReleaseAdapters ();
00305 sBuffer.clear ();
00306 }
00307
00308
00309 void BnPython::Prepare (IdcRequest* preq, IdcResponse* pres, IdcAdaptersSet* pset)
00310 {
00311 pReq = preq;
00312 pRes = pres;
00313 pSet = pset;
00314 }
00315
00316
00317 bool BnPython::Process (BufferHolder code, BufferHolder& result, int size_limit)
00318 {
00319 bool ret_val = true;
00320 nSizeLimit = size_limit;
00321 sBuffer.clear ();
00322 if (code.empty ()) return false;
00323
00324 bExit = false;
00325
00326 string tmp (code.pointer, code.size);
00327 int place;
00328 while ((place = tmp.find ("\r")) != string::npos)
00329 tmp.replace (place, 1, "");
00330
00331 PyEval_AcquireLock();
00332 PyThreadState_Swap(oTS);
00333
00334 PyRun_SimpleString("sys.stdout = cStringIO.StringIO()\nsys.stderr = cStringIO.StringIO()");
00335
00336 ret_val = PyRun_SimpleString(tmp.c_str ()) > -1;
00337 if (!ret_val && !bExit)
00338 PyRun_SimpleString("bn_print ('\\n<P><PRE>\\n', sys.stderr.getvalue(), '\\n</PRE></P>\\n')");
00339
00340 PyRun_SimpleString("bn_print (sys.stdout.getvalue())");
00341 PyRun_SimpleString("sys.stdout.close()\nsys.stderr.close()");
00342
00343 PyThreadState_Swap(NULL);
00344 PyEval_ReleaseLock();
00345
00346 ReleaseAdapters ();
00347
00348 if (nException != 0) throw nException;
00349 result.set (sBuffer.c_str ());
00350 return ret_val || bExit;
00351 }
00352
00353 void BnPython::ReleaseAdapters ()
00354 {
00355 if (pSet)
00356 {
00357 for (set<unsigned int>::iterator itr = oAdaptersList.begin ();
00358 itr != oAdaptersList.end (); ++itr)
00359 pSet->AdapterDone (*itr);
00360
00361 }
00362 oAdaptersList.clear ();
00363 }
00364
00365 bool BnPython::CheckSizeLimit ()
00366 {
00367 if (nSizeLimit == 0 || sBuffer.size () < nSizeLimit)
00368 return true;
00369 PyErr_SetString(PyExc_SystemError, "Reached the buffer size limit");
00370 return false;
00371 }
00372