static ssize_t python_pread(vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n, off_t offset) { struct pyfuncs *pf = handle->data; PyObject *pArgs, *pRet, *pValue; char *pydata; ssize_t s; if (!pf->pFuncPRead) { off_t original_pos; /* * Simulate pread with lseek and read (like the default implementation * does. */ if ((original_pos = python_lseek(handle, fsp, 0, SEEK_CUR)) == -1) return -1; if (python_lseek(handle, fsp, offset, SEEK_SET) == -1) return -1; s = python_vfs_read(handle, fsp, data, n); if (python_lseek(handle, fsp, original_pos, SEEK_SET) == -1) return -1; return s; } PY_TUPLE_NEW(3); PY_ADD_TO_TUPLE(fsp->fh->fd, PyInt_FromSsize_t, 0); PY_ADD_TO_TUPLE(n, PyInt_FromSize_t, 1); PY_ADD_TO_TUPLE(offset, PyInt_FromSize_t, 2); PY_CALL_WITH_ARGS(PRead); if (PyString_Check(pRet)) { pydata = PyString_AsString(pRet); if (pydata == NULL) { Py_DECREF(pRet); errno = E_INTERNAL; return -1; } s = PyString_Size(pRet); } else if (PyByteArray_Check(pRet)) { pydata = PyByteArray_AsString(pRet); if (pydata == NULL) { Py_DECREF(pRet); errno = E_INTERNAL; return -1; } s = PyByteArray_Size(pRet); } else { errno = PyInt_AsLong(pRet); Py_DECREF(pRet); return -1; } memcpy(data, pydata, s > n ? n : s); Py_DECREF(pRet); return s; }
int get_bytes_or_bytearray_ln(bp::object buf) { PyObject *py_ba; py_ba = buf.ptr(); if (PyByteArray_Check(py_ba)) return PyByteArray_Size(py_ba); else if (PyBytes_Check(py_ba)) return PyBytes_Size(py_ba); else throw_ba_exception(); return 0; }
PyObject * py_cps_obj_close(PyObject *self, PyObject *args) { cps_api_operation_handle_t *handle=NULL; PyObject *o; if (! PyArg_ParseTuple( args, "O!s", &PyByteArray_Type, &o)) return NULL; handle = (cps_api_operation_handle_t*)PyByteArray_AsString(o); if (PyByteArray_Size(o)!=sizeof(*handle)) { Py_RETURN_FALSE; } Py_RETURN_TRUE; }
PyObject * py_cps_obj_reg(PyObject *self, PyObject *args) { cps_api_operation_handle_t *handle=NULL; PyObject *h,*o; const char *path; if (! PyArg_ParseTuple( args, "O!sO!", &PyByteArray_Type, &h,&path,&PyDict_Type, &o)) return NULL; handle = (cps_api_operation_handle_t*)PyByteArray_AsString(h); if (PyByteArray_Size(h)!=sizeof(*handle)) { py_set_error_string("Invalid handle"); return nullptr; } std::unique_ptr<py_callbacks_t> p (new py_callbacks_t); if (p.get()==NULL) { py_set_error_string("Memory allocation error"); return nullptr; } p->_methods = o; cps_api_registration_functions_t f; memset(&f,0,sizeof(f)); f.handle = *handle; f.context = p.get(); f._read_function = _read_function; f._write_function = _write_function; f._rollback_function = _rollback_function; if (!cps_api_key_from_string(&f.key,path)) { py_set_error_string("Key translation error"); return nullptr; } cps_api_return_code_t rc; { NonBlockingPythonContext l; rc = cps_api_register(&f); } if (rc!=cps_api_ret_code_OK) { Py_RETURN_FALSE; } p.release(); Py_INCREF(o); Py_RETURN_TRUE; }
static bool Command_redirect_iostream(twopence_command_t *cmd, twopence_iofd_t dst, PyObject *object, twopence_buf_t **buf_ret) { if (object == NULL || PyByteArray_Check(object)) { twopence_buf_t *buffer; if (dst == TWOPENCE_STDIN && object == NULL) return true; /* Capture command output in a buffer */ buffer = twopence_command_alloc_buffer(cmd, dst, 65536); twopence_command_ostream_capture(cmd, dst, buffer); if (dst == TWOPENCE_STDIN) { unsigned int count = PyByteArray_Size(object); twopence_buf_ensure_tailroom(buffer, count); twopence_buf_append(buffer, PyByteArray_AsString(object), count); } if (buf_ret) *buf_ret = buffer; } else if (PyFile_Check(object)) { int fd = PyObject_AsFileDescriptor(object); if (fd < 0) { /* If this fails, we could also pull the content into a buffer and then send that */ PyErr_SetString(PyExc_TypeError, "unable to obtain file handle from File object"); return false; } /* We dup() the file descriptor so that we no longer have to worry * about what python does with its File object */ twopence_command_iostream_redirect(cmd, dst, dup(fd), true); } else if (object == Py_None) { /* Nothing */ } else { /* FIXME: we could check for a string type, and in that case interpret that as * the name of a file to write to. */ PyErr_SetString(PyExc_TypeError, "invalid type in stdio attribute"); return false; } return true; }
static ssize_t python_vfs_read(vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n) { struct pyfuncs *pf = handle->data; PyObject *pArgs, *pRet, *pValue; char *pydata; ssize_t s; PY_TUPLE_NEW(2); PY_ADD_TO_TUPLE(fsp->fh->fd, PyInt_FromSsize_t, 0); PY_ADD_TO_TUPLE(n, PyInt_FromSize_t, 1); PY_CALL_WITH_ARGS(Read); if (PyString_Check(pRet)) { pydata = PyString_AsString(pRet); if (pydata == NULL) { Py_DECREF(pRet); errno = E_INTERNAL; return -1; } s = PyString_Size(pRet); } else if (PyByteArray_Check(pRet)) { pydata = PyByteArray_AsString(pRet); if (pydata == NULL) { Py_DECREF(pRet); errno = E_INTERNAL; return -1; } s = PyByteArray_Size(pRet); } else { errno = PyInt_AsLong(pRet); Py_DECREF(pRet); return -1; } memcpy(data, pydata, s > n ? n : s); Py_DECREF(pRet); return s; }
static PyObject* _update_hash(void* hash_state, PyObject* arg_obj) { Py_ssize_t tuple_length; Py_ssize_t tuple_i; PyObject* tuple_obj, *partial_result; #if PY_MAJOR_VERSION >= 3 if (PyBytes_Check(arg_obj)) { XXH32_update(hash_state, PyBytes_AsString(arg_obj), PyBytes_Size(arg_obj)); } #else if (PyString_Check(arg_obj)) { XXH32_update(hash_state, PyString_AsString(arg_obj), PyString_Size(arg_obj)); } #endif else if (PyByteArray_Check(arg_obj)) { XXH32_update(hash_state, PyByteArray_AsString(arg_obj), PyByteArray_Size(arg_obj)); } else if (PyTuple_Check(arg_obj)) { tuple_length = PyTuple_GET_SIZE(arg_obj); for(tuple_i = 0; tuple_i < tuple_length; tuple_i++) { tuple_obj = PyTuple_GetItem(arg_obj, tuple_i); partial_result = _update_hash(hash_state, tuple_obj); // Check exceptions if (partial_result == NULL) return NULL; } } else if (arg_obj == Py_None) { Py_RETURN_NONE; } else if (PyUnicode_Check(arg_obj)) { PyErr_SetString(PyExc_TypeError, "Found unicode string, you must convert to bytes/str before hashing."); return NULL; } else { PyErr_Format(PyExc_TypeError, "Tried to hash unsupported type: %S.", Py_TYPE(arg_obj)); return NULL; } Py_RETURN_NONE; }
static bool GetByteArrayInfo(Cursor* cur, Py_ssize_t index, PyObject* param, ParamInfo& info) { info.ValueType = SQL_C_BINARY; Py_ssize_t cb = PyByteArray_Size(param); if (cb <= cur->cnxn->binary_maxlength) { info.ParameterType = SQL_VARBINARY; info.ParameterValuePtr = (SQLPOINTER)PyByteArray_AsString(param); info.BufferLength = cb; info.ColumnSize = (SQLUINTEGER)max(cb, 1); info.StrLen_or_Ind = cb; } else { info.ParameterType = SQL_LONGVARBINARY; info.ParameterValuePtr = param; info.ColumnSize = (SQLUINTEGER)cb; info.BufferLength = sizeof(PyObject*); // How big is ParameterValuePtr; ODBC copies it and gives it back in SQLParamData info.StrLen_or_Ind = cur->cnxn->need_long_data_len ? SQL_LEN_DATA_AT_EXEC((SQLLEN)cb) : SQL_DATA_AT_EXEC; } return true; }
int Transfer_build_send(twopence_Transfer *self, twopence_file_xfer_t *xfer) { twopence_file_xfer_init(xfer); xfer->remote.name = self->remote_filename; xfer->remote.mode = self->permissions; xfer->user = self->user; /* xfer->timeout = self->timeout; */ if (self->local_filename) { int rv; rv = twopence_iostream_open_file(self->local_filename, &xfer->local_stream); if (rv < 0) return -1; } else if (self->buffer != NULL && PyByteArray_Check(self->buffer)) { unsigned int count; twopence_buf_destroy(&self->databuf); count = PyByteArray_Size(self->buffer); twopence_buf_ensure_tailroom(&self->databuf, count); twopence_buf_append(&self->databuf, PyByteArray_AsString(self->buffer), count); if (twopence_iostream_wrap_buffer(&self->databuf, false, &xfer->local_stream) < 0) { PyErr_SetString(PyExc_TypeError, "Cannot convert xfer buffer"); return -1; } } else { /* We don't know what to send */ PyErr_SetString(PyExc_TypeError, "Transfer object specifies neither localfile nor buffer"); return -1; } return 0; }
static PyObject * pytrap_init(PyObject *self, PyObject *args, PyObject *keywds) { char **argv = NULL; char *arg; PyObject *argvlist; PyObject *strObj; int argc = 0, i, ifcin = 1, ifcout = 0; static char *kwlist[] = {"argv", "ifcin", "ifcout", NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!|ii", kwlist, &PyList_Type, &argvlist, &ifcin, &ifcout)) { return NULL; } argc = PyList_Size(argvlist); if (argc ==0) { PyErr_SetString(TrapError, "argv list must not be empty."); return NULL; } argv = calloc(argc, sizeof(char *)); for (i=0; i<argc; i++) { strObj = PyList_GetItem(argvlist, i); #if PY_MAJOR_VERSION >= 3 if (!PyUnicode_Check(strObj)) { #else if (!PyString_Check(strObj)) { #endif PyErr_SetString(TrapError, "argv must contain string."); goto failure; } #if PY_MAJOR_VERSION >= 3 arg = PyUnicode_AsUTF8AndSize(strObj, NULL); #else arg = PyString_AS_STRING(strObj); #endif argv[i] = arg; } int ret = local_trap_init(argc, argv, module_info, ifcin, ifcout); if (ret != 0) { PyErr_SetString(TrapError, "Initialization failed"); return NULL; } Py_RETURN_NONE; failure: free(argv); return NULL; } static PyObject * pytrap_send(PyObject *self, PyObject *args, PyObject *keywds) { uint32_t ifcidx = 0; PyObject *dataObj; char *data; Py_ssize_t data_size; static char *kwlist[] = {"data", "ifcidx", NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|I", kwlist, &dataObj, &ifcidx)) { return NULL; } if (PyByteArray_Check(dataObj)) { data_size = PyByteArray_Size(dataObj); data = PyByteArray_AsString(dataObj); } else if (PyBytes_Check(dataObj)) { PyBytes_AsStringAndSize(dataObj, &data, &data_size); } else { PyErr_SetString(PyExc_TypeError, "Argument data must be of bytes or bytearray type."); return NULL; } if (data_size > 0xFFFF) { PyErr_SetString(TrapError, "Data length is out of range (0-65535)"); return NULL; } int ret; Py_BEGIN_ALLOW_THREADS ret = trap_send(ifcidx, data, (uint16_t) data_size); Py_END_ALLOW_THREADS if (ret == TRAP_E_TIMEOUT) { PyErr_SetString(TimeoutError, "Timeout"); return NULL; } else if (ret == TRAP_E_BAD_IFC_INDEX) { PyErr_SetString(TrapError, "Bad index of IFC."); return NULL; } else if (ret == TRAP_E_TERMINATED) { PyErr_SetString(TrapTerminated, "IFC was terminated."); return NULL; } Py_RETURN_NONE; }
static PyObject * pyhashxx_hashxx(PyObject* self, PyObject *args, PyObject *kwds) { unsigned int seed = 0; const char* err_msg = NULL; PyObject* err_obj = NULL; Py_ssize_t args_len = 0; unsigned int digest = 0; void* state = NULL; if (kwds != NULL) { Py_ssize_t kwds_size = PyDict_Size(kwds); PyObject* seed_obj = PyDict_GetItemString(kwds, "seed"); if (kwds_size > 1) { err_msg = "Unexpected keyword arguments, only 'seed' is supported."; goto badarg; } if (kwds_size == 1) { if (seed_obj == NULL) { err_msg = "Unexpected keyword argument, only 'seed' is supported."; goto badarg; } #if PY_MAJOR_VERSION < 3 if (PyInt_Check(seed_obj)) seed = PyInt_AsLong(seed_obj); else #endif if (PyLong_Check(seed_obj)) seed = PyLong_AsLong(seed_obj); else { err_msg = "Unexpected seed value type: %S"; err_obj = seed_obj; goto badseed; } } } args_len = PyTuple_GET_SIZE(args); if (args_len == 0) { err_msg = "Received no arguments to be hashed."; goto badarg; } // If possible, use the shorter, faster version that elides // allocating the state variable because it knows there is only // one input. if (args_len == 1) { PyObject* hash_obj = PyTuple_GetItem(args, 0); int did_hash = 1; #if PY_MAJOR_VERSION >= 3 if (PyBytes_Check(hash_obj)) { digest = XXH32(PyBytes_AsString(hash_obj), PyBytes_Size(hash_obj), seed); } #else if (PyString_Check(hash_obj)) { digest = XXH32(PyString_AsString(hash_obj), PyString_Size(hash_obj), seed); } #endif else if (PyByteArray_Check(hash_obj)) { digest = XXH32(PyByteArray_AsString(hash_obj), PyByteArray_Size(hash_obj), seed); } else if (hash_obj == Py_None) { // Nothing to hash digest = XXH32("", 0, seed); } else { did_hash = 0; } if (did_hash) return Py_BuildValue("I", digest); } // Otherwise, do it the long, slower way state = XXH32_init(seed); if (_update_hash(state, args) == NULL) { XXH32_destroy(state); return NULL; } digest = XXH32_digest(state); XXH32_destroy(state); return Py_BuildValue("I", digest); badarg: PyErr_SetString(PyExc_TypeError, err_msg); return NULL; badseed: PyErr_Format(PyExc_TypeError, err_msg, Py_TYPE(err_obj)); return NULL; }
PyObject* Effect::wrapSetColor(PyObject *self, PyObject *args) { // get the effect Effect * effect = getEffect(); // check if we have aborted already if (effect->_abortRequested) { return Py_BuildValue(""); } // determine the timeout int timeout = effect->_timeout; if (timeout > 0) { timeout = effect->_endTime - QDateTime::currentMSecsSinceEpoch(); // we are done if the time has passed if (timeout <= 0) { return Py_BuildValue(""); } } // check the number of arguments int argCount = PyTuple_Size(args); if (argCount == 3) { // three seperate arguments for red, green, and blue ColorRgb color; if (PyArg_ParseTuple(args, "bbb", &color.red, &color.green, &color.blue)) { std::fill(effect->_colors.begin(), effect->_colors.end(), color); effect->setColors(effect->_priority, effect->_colors, timeout, false); return Py_BuildValue(""); } else { return nullptr; } } else if (argCount == 1) { // bytearray of values PyObject * bytearray = nullptr; if (PyArg_ParseTuple(args, "O", &bytearray)) { if (PyByteArray_Check(bytearray)) { size_t length = PyByteArray_Size(bytearray); if (length == 3 * effect->_imageProcessor->getLedCount()) { char * data = PyByteArray_AS_STRING(bytearray); memcpy(effect->_colors.data(), data, length); effect->setColors(effect->_priority, effect->_colors, timeout, false); return Py_BuildValue(""); } else { PyErr_SetString(PyExc_RuntimeError, "Length of bytearray argument should be 3*ledCount"); return nullptr; } } else { PyErr_SetString(PyExc_RuntimeError, "Argument is not a bytearray"); return nullptr; } } else { return nullptr; } } else { PyErr_SetString(PyExc_RuntimeError, "Function expect 1 or 3 arguments"); return nullptr; } // error PyErr_SetString(PyExc_RuntimeError, "Unknown error"); return nullptr; }
static nxweb_result python_on_request(nxweb_http_server_connection* conn, nxweb_http_request* req, nxweb_http_response* resp) { nxb_buffer* nxb=req->nxb; nxweb_handler* handler=conn->handler; const char* request_uri=req->uri; char* query_string=strchr(request_uri, '?'); int ulen=query_string? (query_string-request_uri) : strlen(request_uri); if (query_string) query_string++; int pfxlen=req->path_info? (req->path_info - req->uri) : 0; int plen=ulen-pfxlen; const char* path_info=request_uri+pfxlen; if (handler->uri && *handler->uri) { pfxlen=strlen(handler->uri); ulen=pfxlen+plen; char* u=nxb_alloc_obj(nxb, ulen+1); memcpy(u, handler->uri, pfxlen); memcpy(u+pfxlen, path_info, plen); u[ulen]='\0'; request_uri=u; path_info=request_uri+pfxlen; } const char* host_port=req->host? strchr(req->host, ':') : 0; int content_fd=0; if (req->content_length) { nxd_fwbuffer* fwb=nxweb_get_request_data(req, PYTHON_HANDLER_KEY).ptr; if (fwb) { if (fwb->error || fwb->size > fwb->max_size) { nxweb_send_http_error(resp, 413, "Request Entity Too Large"); // most likely cause return NXWEB_ERROR; } else if (req->content_received!=fwb->size) { nxweb_log_error("content_received does not match upload stored size for %s", req->uri); nxweb_send_http_error(resp, 500, "Internal Server Error"); return NXWEB_ERROR; } else { content_fd=fwb->fd; if (lseek(content_fd, 0, SEEK_SET)==-1) { nxweb_log_error("can't lseek() temp upload file for %s", req->uri); nxweb_send_http_error(resp, 500, "Internal Server Error"); return NXWEB_ERROR; } } } } nxweb_log_debug("invoke python"); PyGILState_STATE gstate=PyGILState_Ensure(); PyObject* py_func_args=PyTuple_New(1); PyObject* py_environ=PyDict_New(); assert(PyDict_Check(py_environ)); dict_set(py_environ, "SERVER_NAME", PyString_FromStringAndSize(req->host, host_port? (host_port-req->host) : strlen(req->host))); dict_set(py_environ, "SERVER_PORT", PyString_FromString(host_port? host_port+1 : "")); dict_set(py_environ, "SERVER_PROTOCOL", PyString_FromString(req->http11? "HTTP/1.1" : "HTTP/1.0")); dict_set(py_environ, "SERVER_SOFTWARE", PyString_FromString(PACKAGE_STRING)); dict_set(py_environ, "GATEWAY_INTERFACE", PyString_FromString("CGI/1.1")); dict_set(py_environ, "REQUEST_METHOD", PyString_FromString(req->method)); dict_set(py_environ, "REQUEST_URI", PyString_FromStringAndSize(request_uri, ulen)); dict_set(py_environ, "SCRIPT_NAME", PyString_FromStringAndSize(request_uri, pfxlen)); dict_set(py_environ, "PATH_INFO", PyString_FromStringAndSize(path_info, plen)); dict_set(py_environ, "QUERY_STRING", PyString_FromString(query_string? query_string : "")); dict_set(py_environ, "REMOTE_ADDR", PyString_FromString(conn->remote_addr)); dict_set(py_environ, "CONTENT_TYPE", PyString_FromString(req->content_type? req->content_type : "")); dict_set(py_environ, "CONTENT_LENGTH", PyInt_FromLong(req->content_received)); if (req->cookie) dict_set(py_environ, "HTTP_COOKIE", PyString_FromString(req->cookie)); if (req->host) dict_set(py_environ, "HTTP_HOST", PyString_FromString(req->host)); if (req->user_agent) dict_set(py_environ, "HTTP_USER_AGENT", PyString_FromString(req->user_agent)); if (req->if_modified_since) { struct tm tm; gmtime_r(&req->if_modified_since, &tm); char ims[32]; nxweb_format_http_time(ims, &tm); dict_set(py_environ, "HTTP_IF_MODIFIED_SINCE", PyString_FromString(ims)); } if (req->headers) { // write added headers // encode http headers into CGI variables; see 4.1.18 in https://tools.ietf.org/html/rfc3875 char hname[256]; memcpy(hname, "HTTP_", 5); char* h=hname+5; nx_simple_map_entry* itr; for (itr=nx_simple_map_itr_begin(req->headers); itr; itr=nx_simple_map_itr_next(itr)) { nx_strtoupper(h, itr->name); char* p; for (p=h; *p; p++) { if (*p=='-') *p='_'; } dict_set(py_environ, hname, PyString_FromString(itr->value)); } } dict_set(py_environ, "wsgi.url_scheme", PyString_FromString(conn->secure? "https" : "http")); if (req->content_length) { if (content_fd) { dict_set(py_environ, "nxweb.req.content_fd", PyInt_FromLong(content_fd)); } else { dict_set(py_environ, "nxweb.req.content", PyByteArray_FromStringAndSize(req->content? req->content : "", req->content_received)); } } if (req->if_modified_since) dict_set(py_environ, "nxweb.req.if_modified_since", PyLong_FromLong(req->if_modified_since)); dict_set(py_environ, "nxweb.req.uid", PyLong_FromLongLong(req->uid)); if (req->parent_req) { nxweb_http_request* preq=req->parent_req; while (preq->parent_req) preq=preq->parent_req; // find root request if (preq->uid) { dict_set(py_environ, "nxweb.req.root_uid", PyLong_FromLongLong(preq->uid)); } } // call python PyTuple_SetItem(py_func_args, 0, py_environ); PyObject* py_result=PyObject_CallObject(py_nxweb_on_request_func, py_func_args); Py_DECREF(py_func_args); if (py_result && PyTuple_Check(py_result) && PyTuple_Size(py_result)==3) { PyObject* py_status=PyTuple_GET_ITEM(py_result, 0); PyObject* py_headers=PyTuple_GET_ITEM(py_result, 1); PyObject* py_body=PyTuple_GET_ITEM(py_result, 2); if (py_status && PyString_Check(py_status)) { const char* status_string=PyString_AS_STRING(py_status); int status_code=0; const char* p=status_string; while (*p && *p>='0' && *p<='9') { status_code=status_code*10+(*p-'0'); p++; } while (*p && *p==' ') p++; if (status_code>=200 && status_code<600 && *p) { resp->status_code=status_code; resp->status=nxb_copy_str(nxb, p); } } if (py_headers && PyList_Check(py_headers)) { const int size=PyList_Size(py_headers); int i; for (i=0; i<size; i++) { PyObject* py_header_tuple=PyList_GET_ITEM(py_headers, i); if (py_header_tuple && PyTuple_Check(py_header_tuple) && PyTuple_Size(py_header_tuple)==2) { PyObject* py_name=PyTuple_GET_ITEM(py_header_tuple, 0); PyObject* py_value=PyTuple_GET_ITEM(py_header_tuple, 1); if (py_name && PyString_Check(py_name) && py_value && PyString_Check(py_value)) { nxweb_add_response_header_safe(resp, PyString_AS_STRING(py_name), PyString_AS_STRING(py_value)); } } } } if ((!resp->status_code || resp->status_code==200) && !resp->content_type) resp->content_type="text/html"; char* rcontent=0; nxe_ssize_t rsize=0; if (PyByteArray_Check(py_body)) { rcontent=PyByteArray_AS_STRING(py_body); rsize=PyByteArray_Size(py_body); } else if (PyString_Check(py_body)) { rcontent=PyString_AS_STRING(py_body); rsize=PyString_Size(py_body); } if (rcontent && rsize>0) nxweb_response_append_data(resp, rcontent, rsize); } else if (py_result && PyString_Check(py_result)) { resp->status_code=500; resp->status="Internal Server Error"; resp->content_type="text/html"; nxweb_log_error("python call failed: %s", PyString_AS_STRING(py_result)); nxweb_response_printf(resp, "python call failed: %H", PyString_AS_STRING(py_result)); } else { PyErr_Print(); nxweb_log_error("python call failed"); nxweb_response_printf(resp, "python call failed"); } Py_XDECREF(py_result); // Release the thread. No Python API allowed beyond this point. PyGILState_Release(gstate); nxweb_log_debug("invoke python complete"); return NXWEB_OK; }
/* ******************************************************************************************************* * Checks serializer_policy. * Serializes Py_Object (value) into as_bytes using serialization logic * based on serializer_policy. * * @param serializer_policy The serializer_policy to be used to handle * the serialization. * @param bytes The as_bytes to be set. * @param value The value to be serialized. * @param error_p The as_error to be populated by the function * with encountered error if any. ******************************************************************************************************* */ extern PyObject * serialize_based_on_serializer_policy(AerospikeClient * self, int32_t serializer_policy, as_bytes **bytes, PyObject *value, as_error *error_p) { uint8_t use_client_serializer = true; PyObject* initresult = NULL; if (self->is_client_put_serializer) { if (serializer_policy == SERIALIZER_USER) { if (!self->user_serializer_call_info.callback) { use_client_serializer = false; } } } else if (self->user_serializer_call_info.callback) { serializer_policy = SERIALIZER_USER; } switch(serializer_policy) { case SERIALIZER_NONE: as_error_update(error_p, AEROSPIKE_ERR_PARAM, "Cannot serialize: SERIALIZER_NONE selected"); goto CLEANUP; case SERIALIZER_PYTHON: { /* * Serialize bytearray as is and store them into database with * type AS_BYTES_BLOB, unlike other values in case of * SERIALIZER_PYTHON. * This is a special case. * Refer: AER-3589 for more details. */ if (PyByteArray_Check(value)) { uint8_t *bytes_array = (uint8_t *) PyByteArray_AsString(value); uint32_t bytes_array_len = (uint32_t) PyByteArray_Size(value); set_as_bytes(bytes, bytes_array, bytes_array_len, AS_BYTES_BLOB, error_p); } else { /* get the sys.modules dictionary */ PyObject* sysmodules = PyImport_GetModuleDict(); PyObject* cpickle_module = NULL; if(PyMapping_HasKeyString(sysmodules, "cPickle")) { cpickle_module = PyMapping_GetItemString(sysmodules, "cPickle"); } else { cpickle_module = PyImport_ImportModule("cPickle"); } if(!cpickle_module) { /* insert error handling here! and exit this function */ as_error_update(error_p, AEROSPIKE_ERR_CLIENT, "Unable to load cpickle module"); goto CLEANUP; } else { PyObject * py_funcname = PyStr_FromString("dumps"); Py_INCREF(cpickle_module); initresult = PyObject_CallMethodObjArgs(cpickle_module, py_funcname, value, NULL); Py_DECREF(cpickle_module); Py_DECREF(py_funcname); if(!initresult) { /* more error handling &c */ as_error_update(error_p, AEROSPIKE_ERR_CLIENT, "Unable to call dumps function"); goto CLEANUP; } else { Py_INCREF(initresult); char *return_value = PyStr_AsString(initresult); Py_ssize_t len = PyBytes_GET_SIZE(initresult); set_as_bytes(bytes, (uint8_t *) return_value, len, AS_BYTES_PYTHON, error_p); Py_DECREF(initresult); } } Py_XDECREF(cpickle_module); } } break; case SERIALIZER_JSON: /* * TODO: * Handle JSON serialization after support for AS_BYTES_JSON * is added in aerospike-client-c */ as_error_update(error_p, AEROSPIKE_ERR, "Unable to serialize using standard json serializer"); goto CLEANUP; case SERIALIZER_USER: if (use_client_serializer) { execute_user_callback(&self->user_serializer_call_info, bytes, &value, true, error_p); if (AEROSPIKE_OK != (error_p->code)) { goto CLEANUP; } } else { if (is_user_serializer_registered) { execute_user_callback(&user_serializer_call_info, bytes, &value, true, error_p); if (AEROSPIKE_OK != (error_p->code)) { goto CLEANUP; } } else if (self->user_serializer_call_info.callback) { execute_user_callback(&self->user_serializer_call_info, bytes, &value, true, error_p); if (AEROSPIKE_OK != (error_p->code)) { goto CLEANUP; } } else { as_error_update(error_p, AEROSPIKE_ERR, "No serializer callback registered"); goto CLEANUP; } } break; default: as_error_update(error_p, AEROSPIKE_ERR, "Unsupported serializer"); goto CLEANUP; } CLEANUP: Py_XDECREF(initresult); if ( error_p->code != AEROSPIKE_OK ) { PyObject * py_err = NULL; error_to_pyobject(error_p, &py_err); PyObject *exception_type = raise_exception(error_p); PyErr_SetObject(exception_type, py_err); Py_DECREF(py_err); return NULL; } return PyLong_FromLong(0); }
PyObject* Effect::wrapSetImage(PyObject *self, PyObject *args) { // get the effect Effect * effect = getEffect(); // check if we have aborted already if (effect->_abortRequested) { return Py_BuildValue(""); } // determine the timeout int timeout = effect->_timeout; if (timeout > 0) { timeout = effect->_endTime - QDateTime::currentMSecsSinceEpoch(); // we are done if the time has passed if (timeout <= 0) { return Py_BuildValue(""); } } // bytearray of values int width, height; PyObject * bytearray = nullptr; if (PyArg_ParseTuple(args, "iiO", &width, &height, &bytearray)) { if (PyByteArray_Check(bytearray)) { int length = PyByteArray_Size(bytearray); if (length == 3 * width * height) { Image<ColorRgb> image(width, height); char * data = PyByteArray_AS_STRING(bytearray); memcpy(image.memptr(), data, length); effect->_imageProcessor->process(image, effect->_colors); effect->setColors(effect->_priority, effect->_colors, timeout, false); return Py_BuildValue(""); } else { PyErr_SetString(PyExc_RuntimeError, "Length of bytearray argument should be 3*width*height"); return nullptr; } } else { PyErr_SetString(PyExc_RuntimeError, "Argument 3 is not a bytearray"); return nullptr; } } else { return nullptr; } // error PyErr_SetString(PyExc_RuntimeError, "Unknown error"); return nullptr; }
void PythonTransform::transform(const QByteArray &input, QByteArray &output) { if (input.isEmpty()) return; PyGILState_STATE lgstate; lgstate = PyGILState_Ensure(); if (loadModule()) { PyObject * pyInbound = Py_False; // needs reference count management if (twoWays) pyInbound = (wayValue == INBOUND ? Py_True : Py_False ); Py_INCREF(pyInbound); if (PyModule_AddObject(pModule, PythonModules::INBOUND_ATTR_NAME, pyInbound) == -1) { // steal reference pythonmgm->checkPyError(); logError(tr("T_T Could not set the direction value properly:\n%1").arg(pythonmgm->getLastError()),id); Py_XDECREF(pyInbound); PyGILState_Release(lgstate); return; } PyObject *paramsdict = PyDict_New(); // setting an empty dictionary // setting parameters in the python environment if (!parameters.isEmpty()) { if (!pythonmgm->checkPyError()) { logError(tr("T_T Error while creating the Python parameter dict:\n%1").arg(pythonmgm->getLastError()), id); Py_XDECREF(paramsdict); PyGILState_Release(lgstate); return; } // adding parameters to the python list QHashIterator<QByteArray, QByteArray> i(parameters); while (i.hasNext()) { i.next(); PyObject* paramKey = PyUnicode_FromStringAndSize(i.key(),i.key().size()); if (!pythonmgm->checkPyError()) { logError(tr("T_T Error while creating Python parameter key:\n%1").arg(pythonmgm->getLastError()), id); Py_XDECREF(paramsdict); PyGILState_Release(lgstate); return; } PyObject* paramValue = PyUnicode_FromStringAndSize(i.value(),i.value().size()); if (!pythonmgm->checkPyError()) { logError(tr("T_T Error while creating Python parameter value:\n%1").arg(pythonmgm->getLastError()), id); Py_XDECREF(paramsdict); Py_XDECREF(paramKey); PyGILState_Release(lgstate); return; } if (PyDict_SetItem(paramsdict,paramKey,paramValue) == -1) { // not stealing reference pythonmgm->checkPyError(); // we already know there was an error logError(tr("T_T Error while setting Python parameter pair:\n%1").arg(pythonmgm->getLastError()), id); Py_XDECREF(paramsdict); Py_XDECREF(paramKey); Py_XDECREF(paramValue); PyGILState_Release(lgstate); return; } // Cleaning the values (references not stolen) Py_XDECREF(paramKey); Py_XDECREF(paramValue); } } // setting the dictionary in any case, even if it is empty if (PyModule_AddObject(pModule,PythonModules::PARAMS_ATTR_NAME , paramsdict) == -1) { // stolen paramsdict reference pythonmgm->checkPyError(); logError(tr("T_T Could not set the Pip3line_params value properly:\n%1").arg(pythonmgm->getLastError()),id); } PyObject * pFunc = PyObject_GetAttrString(pModule, PythonModules::MAIN_FUNCTION_NAME); if (pythonmgm->checkPyError() && PyCallable_Check(pFunc)) { PyObject* pArgs = PyTuple_New(1); if (!pythonmgm->checkPyError()) { Q_EMIT error(tr("T_T Error while creating the Python argument tuple:\n%1").arg(pythonmgm->getLastError()), id); Py_XDECREF(pFunc); Py_XDECREF(pArgs); PyGILState_Release(lgstate); return; } PyObject* inputPy = PyByteArray_FromStringAndSize(input.data(),input.size()); if (!pythonmgm->checkPyError()) { Q_EMIT error(tr("T_T Error while creating the Python byte array:\n%1").arg(pythonmgm->getLastError()), id); Py_XDECREF(pFunc); Py_XDECREF(pArgs); Py_XDECREF(inputPy); PyGILState_Release(lgstate); return; } if (PyTuple_SetItem(pArgs, 0, inputPy) != 0) {// stealing the reference of inputPy pythonmgm->checkPyError(); Q_EMIT error(tr("T_T Error while creating the Python byte array:\n%1").arg(pythonmgm->getLastError()), id); Py_XDECREF(inputPy); Py_XDECREF(pFunc); Py_XDECREF(pArgs); PyGILState_Release(lgstate); return; } PyObject* returnValue = PyObject_CallObject(pFunc, pArgs); // new ref or NULL if (!pythonmgm->checkPyError()) { Q_EMIT error(tr("T_T Python error while executing the function:\n %1").arg(pythonmgm->getLastError()), id); } else { if (PyByteArray_Check(returnValue)) { Py_ssize_t templength = PyByteArray_Size(returnValue); if (templength > BLOCK_MAX_SIZE) { templength = BLOCK_MAX_SIZE; Q_EMIT warning(tr("Data block returned is too large, truncating."),id); } char * buffer = PyByteArray_AsString(returnValue); // never to be deleted output.append(QByteArray(buffer,static_cast<int>(templength))); // safe cast as value was checked earlier } else { Q_EMIT error(tr("The Python object returned is not a bytearray"), id); } } Py_XDECREF(returnValue); Py_XDECREF(pArgs); // Py_DECREF(inputPy); // stolen reference, don't touch that Py_XDECREF(pFunc); } else { Q_EMIT error(tr("Python error while calling the function %1():\n%2").arg(PythonModules::MAIN_FUNCTION_NAME).arg(pythonmgm->getLastError()), id); } } else { qDebug() << "[Python transform] could not load the module"; } PyGILState_Release(lgstate); }
QImage QPythonImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize) { QImage img; // Image data (and metadata) returned from Python PyObject *pixels = NULL; int width = 0, height = 0; int format = 0; // For counting the number of required bytes int bitsPerPixel = 0; size_t requiredBytes = 0; size_t actualBytes = 0; QPythonPriv *priv = QPythonPriv::instance(); if (!priv) { qWarning() << "Python component not instantiated yet"; return QImage(); } if (!priv->image_provider) { qWarning() << "No image provider set in Python code"; return QImage(); } QByteArray id_utf8 = id.toUtf8(); // Image provider implementation in Python: // // import pyotherside // // def image_provider(image_id, requested_size): // if requested_size == (-1, -1): // requested_size = 100, 200 # some sane default size // width, height = requested_size // pixels = ... // format = pyotherside.format_argb32 # or some other format // return (bytearray(pixels), (width, height), format) // // pyotherside.set_image_provider(image_provider) ENSURE_GIL_STATE; PyObjectRef args(Py_BuildValue("(N(ii))", PyUnicode_FromString(id_utf8.constData()), requestedSize.width(), requestedSize.height()), true); PyObjectRef result(PyObject_Call(priv->image_provider.borrow(), args.borrow(), NULL), true); if (!result) { qDebug() << "Error while calling the image provider"; PyErr_Print(); goto cleanup; } if (!PyArg_ParseTuple(result.borrow(), "O(ii)i", &pixels, &width, &height, &format)) { PyErr_Clear(); qDebug() << "Image provider must return (pixels, (width, height), format)"; goto cleanup; } if (!PyByteArray_Check(pixels)) { qDebug() << "Image data must be a Python bytearray()"; goto cleanup; } switch (format) { case PYOTHERSIDE_IMAGE_FORMAT_ENCODED: /* pyotherside.format_data */ break; case PYOTHERSIDE_IMAGE_FORMAT_SVG: /* pyotherside.format_svg_data */ break; case QImage::Format_Mono: case QImage::Format_MonoLSB: bitsPerPixel = 1; break; case QImage::Format_RGB32: case QImage::Format_ARGB32: bitsPerPixel = 32; break; case QImage::Format_RGB16: case QImage::Format_RGB555: case QImage::Format_RGB444: bitsPerPixel = 16; break; case QImage::Format_RGB666: case QImage::Format_RGB888: bitsPerPixel = 24; break; default: qDebug() << "Invalid format:" << format; goto cleanup; } requiredBytes = (bitsPerPixel * width * height + 7) / 8; actualBytes = PyByteArray_Size(pixels); // QImage requires scanlines to be 32-bit aligned. Scanlines from Python // are considered to be tightly packed, we have to check for alignment. // While we could re-pack the data to be aligned, we don't want to do that // for performance reasons. // If we're using 32-bit data (e.g. ARGB32), it will always be aligned. if (format >= 0 && bitsPerPixel != 32) { if ((bitsPerPixel * width) % 32 != 0) { // If actualBytes > requiredBytes, we can check if there are enough // bytes to consider the data 32-bit aligned (from Python) and avoid // the error (scanlines must be padded to multiples of 4 bytes) if ((unsigned int)(((width * bitsPerPixel / 8 + 3) / 4) * 4 * height) == actualBytes) { qDebug() << "Assuming 32-bit aligned scanlines from Python"; } else { qDebug() << "Each scanline of data must be 32-bit aligned"; goto cleanup; } } } if (format >= 0 && requiredBytes > actualBytes) { qDebug() << "Format" << (enum QImage::Format)format << "at size" << QSize(width, height) << "requires at least" << requiredBytes << "bytes of image data, got only" << actualBytes << "bytes"; goto cleanup; } if (format < 0) { switch (format) { case PYOTHERSIDE_IMAGE_FORMAT_ENCODED: { // Pixel data is actually encoded image data that we need to decode img.loadFromData((const unsigned char*)PyByteArray_AsString(pixels), PyByteArray_Size(pixels)); break; } case PYOTHERSIDE_IMAGE_FORMAT_SVG: { // Convert the Python byte array to a QByteArray QByteArray svgDataArray(PyByteArray_AsString(pixels), PyByteArray_Size(pixels)); // Load the SVG data to the SVG renderer QSvgRenderer renderer(svgDataArray); // Handle width, height or both not being set QSize defaultSize = renderer.defaultSize(); int defaultWidth = defaultSize.width(); int defaultHeight = defaultSize.height(); if (width < 0 && height < 0) { // Both Width and Height have not been set - use the defaults from the SVG data // (each SVG image has a default size) // NOTE: we get a -1,-1 requestedSize only if sourceSize is not set at all, // if either width or height is set then the other one is 0, not -1 width = defaultWidth; height = defaultHeight; } else { // At least width or height is valid if (width <= 0) { // Width is not set, use default width scaled according to height to keep // aspect ratio if (defaultHeight != 0) { // Protect from division by zero width = (float)defaultWidth*((float)height/(float)defaultHeight); } } if (height <= 0) { // Height is not set, use default height scaled according to width to keep // aspect ratio if (defaultWidth != 0) { // Protect from division by zero height = (float)defaultHeight*((float)width/(float)defaultWidth); } } } // The pixel data is actually SVG image data that we need to render at correct size // // Note: according to the QImage and QPainter documentation the optimal QImage // format for drawing is Format_ARGB32_Premultiplied img = QImage(width, height, QImage::Format_ARGB32_Premultiplied); // According to the documentation an empty QImage needs to be "flushed" before // being used with QPainter to prevent rendering artifacts from showing up img.fill(Qt::transparent); // Paints the rendered SVG to the QImage instance QPainter painter(&img); renderer.render(&painter); break; } default: qWarning() << "Unknown format" << format << "has been specified and will not be handled."; break; } } else { // Need to keep a reference to the byte array object, as it contains // the backing store data for the QImage. // Will be decref'd by cleanup_python_qimage once the QImage is gone. Py_INCREF(pixels); img = QImage((const unsigned char *)PyByteArray_AsString(pixels), width, height, (enum QImage::Format)format, cleanup_python_qimage, pixels); } cleanup: *size = img.size(); return img; }