Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
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;
}
Beispiel #11
0
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;
}
Beispiel #12
0
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;
}
Beispiel #13
0
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);
}
Beispiel #15
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;
}
Beispiel #16
0
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;
}