Example #1
0
static int
inner_atohl(PyObject *o, unsigned long *ip_ul){
    struct in_addr buf;
    char *ip_addr;

#ifdef IS_PY3K
    if(PyUnicode_CheckExact(o)){
        ip_addr = PyUnicode_AsUTF8(o);
    } else if (PyBytes_CheckExact(o)){
        ip_addr = PyBytes_AsString(o);
    } else if (PyByteArray_CheckExact(o)){
        ip_addr =  PyByteArray_AsString(o);
#else
    if(PyUnicode_CheckExact(o) || PyString_CheckExact(o)){
        ip_addr =  PyString_AsString(o);
    } else if (PyByteArray_CheckExact(o)){
        ip_addr = PyByteArray_AsString(o);
#endif
    } else {
        PyErr_SetString(PyExc_TypeError, "should be built-in string/bytes/byte array");
        return 0;
    }

    if (ip_addr == NULL){
        return 0;
    }

    if (inet_aton(ip_addr, &buf)){
        *ip_ul = ntohl(buf.s_addr);
        return 1;
    }else{
        PyErr_SetString(PyExc_ValueError,
                        "illegal IP address string");
        return 0;
    }
}


static PyObject *
ip_store_atohl(PyObject *self, PyObject *o){

    unsigned long ip_ul;

    if(inner_atohl(o, &ip_ul)){
        return PyLong_FromUnsignedLong(ip_ul);
    }else{
        return NULL;
    }
}
Example #2
0
static char *
fp_readl(char *s, int size, struct tok_state *tok)
{
    PyObject* bufobj;
    const char *buf;
    Py_ssize_t buflen;

    /* Ask for one less byte so we can terminate it */
    assert(size > 0);
    size--;

    if (tok->decoding_buffer) {
        bufobj = tok->decoding_buffer;
        Py_INCREF(bufobj);
    }
    else
    {
        bufobj = PyObject_CallObject(tok->decoding_readline, NULL);
        if (bufobj == NULL)
            goto error;
    }
    if (PyUnicode_CheckExact(bufobj))
    {
        buf = _PyUnicode_AsStringAndSize(bufobj, &buflen);
        if (buf == NULL) {
            goto error;
        }
    }
    else
    {
        buf = PyByteArray_AsString(bufobj);
        if (buf == NULL) {
            goto error;
        }
        buflen = PyByteArray_GET_SIZE(bufobj);
    }

    Py_XDECREF(tok->decoding_buffer);
    if (buflen > size) {
        /* Too many chars, the rest goes into tok->decoding_buffer */
        tok->decoding_buffer = PyByteArray_FromStringAndSize(buf+size,
                                                         buflen-size);
        if (tok->decoding_buffer == NULL)
            goto error;
        buflen = size;
    }
    else
        tok->decoding_buffer = NULL;

    memcpy(s, buf, buflen);
    s[buflen] = '\0';
    if (buflen == 0) /* EOF */
        s = NULL;
    Py_DECREF(bufobj);
    return s;

error:
    Py_XDECREF(bufobj);
    return error_ret(tok);
}
Example #3
0
/* Convert a Python string (including Unicode in Py2 and Bytes in Py3) to a QString */
QString PyString_AsQString(PyObject *pystr)
{
    // Unicode
    if (PyUnicode_Check(pystr))
    {
#if PY_MAJOR_VERSION >= 3
        QString s = QString::fromUtf8(PyUnicode_AsUTF8(pystr));
#else
        PyObject *utf8str = PyUnicode_AsUTF8String(pystr);
        QString s = QString::fromUtf8(PyString_AsString(utf8str));
        Py_DecRef(utf8str);
#endif
        return s;
    }

    // Bytes
#if PY_MAJOR_VERSION >= 3
    else if (PyByteArray_Check(pystr))
        return QString::fromUtf8(PyByteArray_AsString(pystr));
#else
    else if (PyString_Check(pystr))
        return QString::fromUtf8(PyString_AsString(pystr));
#endif
    else
        return QString();
}
static int
Map_init(Map *self, PyObject *args, PyObject *kwds)
{                    
	int size_pixels;
	double size_meters;
	PyObject * py_bytes = NULL;
	
    static char * argnames[] = {"size_pixels", "size_meters", "bytes", NULL};

    if(!PyArg_ParseTupleAndKeywords(args, kwds,"id|O", argnames, 
        &size_pixels, 
        &size_meters, 
        &py_bytes))
    {
        return error_on_raise_argument_exception("Map");
    }
           
    map_init(&self->map, size_pixels, size_meters);
    
    if (py_bytes && !bad_mapbytes(py_bytes, size_pixels, "__init__"))
    {    
        map_set(&self->map, PyByteArray_AsString(py_bytes));
    }
    
    return 0;
}
Example #5
0
static PyObject *
_io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n)
/*[clinic end generated code: output=6cdeb731e3c9f13c input=b6d0dcf6417d1374]*/
{
    PyObject *b, *res;

    if (n < 0) {
        _Py_IDENTIFIER(readall);

        return _PyObject_CallMethodId(self, &PyId_readall, NULL);
    }

    /* TODO: allocate a bytes object directly instead and manually construct
       a writable memoryview pointing to it. */
    b = PyByteArray_FromStringAndSize(NULL, n);
    if (b == NULL)
        return NULL;

    res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, b, NULL);
    if (res == NULL || res == Py_None) {
        Py_DECREF(b);
        return res;
    }

    n = PyNumber_AsSsize_t(res, PyExc_ValueError);
    Py_DECREF(res);
    if (n == -1 && PyErr_Occurred()) {
        Py_DECREF(b);
        return NULL;
    }

    res = PyBytes_FromStringAndSize(PyByteArray_AsString(b), n);
    Py_DECREF(b);
    return res;
}
Example #6
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;
}
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;
}
Example #8
0
char *get_bytes_or_bytearray_str(bp::object buf)
{
    PyObject *py_ba;
    py_ba = buf.ptr();
    if (PyByteArray_Check(py_ba))
        return PyByteArray_AsString(py_ba);
    else if (PyBytes_Check(py_ba))
        return PyBytes_AsString(py_ba);
    else
        throw_ba_exception();
    return NULL;
}
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;
}
Example #10
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;
}
Example #11
0
static PyObject *
Map_get(Map * self, PyObject * args, PyObject * kwds)
{        
    PyObject * py_mapbytes = NULL;

    if (!PyArg_ParseTuple(args, "O", &py_mapbytes))
    {
        return null_on_raise_argument_exception("Map", "get");
    }
    
    if (bad_mapbytes(py_mapbytes, self->map.size_pixels, "get"))
    {
        Py_RETURN_NONE;
    }
    
    map_get(&self->map, PyByteArray_AsString(py_mapbytes));
    
    Py_RETURN_NONE;
}
Example #12
0
static PyObject *bip_ord(term_t t) {
  PyObject *pVal;
  Py_ssize_t size;

  if (!PL_get_arg(1, t, t))
    return NULL;
  pVal = term_to_python(t, true);
  if (PyUnicode_Check(pVal)) {
#if PY_MAJOR_VERSION < 3
    size = PyUnicode_GET_SIZE(pVal);
#else
    size = PyUnicode_GetLength(pVal);
#endif
    if (size == 1) {
#if PY_MAJOR_VERSION < 3
      long ord = (long)*PyUnicode_AS_UNICODE(pVal);
      return PyInt_FromLong(ord);
#else
      Py_UCS4 ord = PyUnicode_ReadChar(pVal, 0);
      return PyLong_FromLong(ord);
#endif
    }
    return NULL;
  } else if (PyByteArray_Check(pVal)) {
    char *s = PyByteArray_AsString(pVal);

    if (s[1])
      return NULL;
#if PY_MAJOR_VERSION < 3
    return PyInt_FromLong(s[0]);
  } else if (PyString_Check(pVal)) {
    char *s = PyString_AsString(pVal);

    if (s[1])
      return NULL;
    return PyInt_FromLong(s[0]);
#else
    return PyLong_FromLong(s[0]);
#endif
  } else
    return NULL;
}
Example #13
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;
}
Example #14
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;
}
Example #15
0
static PyObject *
rawiobase_read(PyObject *self, PyObject *args)
{
    Py_ssize_t n = -1;
    PyObject *b, *res;

    if (!PyArg_ParseTuple(args, "|n:read", &n)) {
        return NULL;
    }

    if (n < 0) {
        _Py_IDENTIFIER(readall);

        return _PyObject_CallMethodId(self, &PyId_readall, NULL);
    }

    /* TODO: allocate a bytes object directly instead and manually construct
       a writable memoryview pointing to it. */
    b = PyByteArray_FromStringAndSize(NULL, n);
    if (b == NULL)
        return NULL;

    res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, b, NULL);
    if (res == NULL || res == Py_None) {
        Py_DECREF(b);
        return res;
    }

    n = PyNumber_AsSsize_t(res, PyExc_ValueError);
    Py_DECREF(res);
    if (n == -1 && PyErr_Occurred()) {
        Py_DECREF(b);
        return NULL;
    }

    res = PyBytes_FromStringAndSize(PyByteArray_AsString(b), n);
    Py_DECREF(b);
    return res;
}
Example #16
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;
}
Example #17
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;
}
/*
 *******************************************************************************************************
 * 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);
}
Example #19
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);
}
Example #20
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;
}
Example #21
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;
}
/**
 *******************************************************************************************************
 * This function invokes csdk's API's.
 *
 * @param self                  AerospikeClient object
 * @param err                   The as_error to be populated by the function
 *                              with the encountered error if any.
 * @param key                   The C client's as_key that identifies the record.
 * @param py_list               The list containing op, bin and value.
 * @param py_meta               The metadata for the operation.
 * @param operate_policy_p      The value for operate policy.
 *******************************************************************************************************
 */
static
PyObject *  AerospikeClient_Operate_Invoke(
	AerospikeClient * self, as_error *err,
	as_key * key, PyObject * py_list, PyObject * py_meta,
	as_policy_operate * operate_policy_p)
{
	as_val* put_val = NULL;
	char* bin = NULL;
	char* val = NULL;
	long offset = 0;
	double double_offset = 0.0;
	uint32_t ttl = 0;
	long operation = 0;
	int i = 0;
	PyObject * py_rec = NULL;
	PyObject * py_ustr = NULL;
	PyObject * py_ustr1 = NULL;
	PyObject * py_bin = NULL;
	as_record * rec = NULL;

	as_static_pool static_pool;
	memset(&static_pool, 0, sizeof(static_pool));

	as_operations ops;
	Py_ssize_t size = PyList_Size(py_list);
	as_operations_inita(&ops, size);

	if (!self || !self->as) {
		as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid aerospike object");
		goto CLEANUP;
	}

	if(py_meta) {
		AerospikeClient_CheckForMeta(py_meta, &ops, err);
	}

	if (err->code != AEROSPIKE_OK) {
		goto CLEANUP;
	}

	for ( i = 0; i < size; i++) {
		PyObject * py_val = PyList_GetItem(py_list, i);
		operation = -1;
		offset = 0;
		double_offset = 0.0;
		if ( PyDict_Check(py_val) ) {
			PyObject *key_op = NULL, *value = NULL;
			PyObject * py_value = NULL;
			Py_ssize_t pos = 0;
			while (PyDict_Next(py_val, &pos, &key_op, &value)) {
				if ( ! PyString_Check(key_op) ) {
					as_error_update(err, AEROSPIKE_ERR_CLIENT, "A operation key must be a string.");
					goto CLEANUP;
				} else {
					char * name = PyString_AsString(key_op);
					if(!strcmp(name,"op") && (PyInt_Check(value) || PyLong_Check(value))) {
						operation = PyInt_AsLong(value);
					} else if (!strcmp(name, "bin")) {
						py_bin = value;
					} else if(!strcmp(name, "val")) {
						py_value = value;
					} else {
						as_error_update(err, AEROSPIKE_ERR_PARAM, "operation can contain only op, bin and val keys");
						goto CLEANUP;
					}
				}
			}

			if (py_bin) {
				if (PyUnicode_Check(py_bin)) {
					py_ustr = PyUnicode_AsUTF8String(py_bin);
					bin = PyString_AsString(py_ustr);
				} else if (PyString_Check(py_bin)) {
					bin = PyString_AsString(py_bin);
				} else if (PyByteArray_Check(py_bin)) {
                    bin = PyByteArray_AsString(py_bin);
                } else {
                    as_error_update(err, AEROSPIKE_ERR_PARAM, "Bin name should be of type string");
					goto CLEANUP;
				}

				if (self->strict_types) {
					if (strlen(bin) > AS_BIN_NAME_MAX_LEN) {
						if (py_ustr) {
							Py_DECREF(py_ustr);
							py_ustr = NULL;
						}
						as_error_update(err, AEROSPIKE_ERR_BIN_NAME, "A bin name should not exceed 14 characters limit");
						goto CLEANUP;
					}
				}
			} else if (!py_bin && operation != AS_OPERATOR_TOUCH) {
				as_error_update(err, AEROSPIKE_ERR_PARAM, "Bin is not given");
				goto CLEANUP;
			}
			if (py_value) {
				if (self->strict_types) {
					if (check_type(self, py_value, operation, err)) {
						goto CLEANUP;
					}
				}
			} else if ((!py_value) && (operation != AS_OPERATOR_READ && operation != AS_OPERATOR_TOUCH)) {
				as_error_update(err, AEROSPIKE_ERR_PARAM, "Value should be given");
				goto CLEANUP;
			}

			switch(operation) {
				case AS_OPERATOR_APPEND:
					if (PyUnicode_Check(py_value)) {
						py_ustr1 = PyUnicode_AsUTF8String(py_value);
						val = PyString_AsString(py_ustr1);
						as_operations_add_append_str(&ops, bin, val);
					} else if (PyString_Check(py_value)) {
						val = PyString_AsString(py_value);
						as_operations_add_append_str(&ops, bin, val);
					} else if (PyByteArray_Check(py_value)) {
						as_bytes *bytes;
						GET_BYTES_POOL(bytes, &static_pool, err);
						serialize_based_on_serializer_policy(self, SERIALIZER_PYTHON, &bytes, py_value, err);
						as_operations_add_append_raw(&ops, bin, bytes->value, bytes->size);
					} else {
						if (!self->strict_types || !strcmp(py_value->ob_type->tp_name, "aerospike.null")) {
							as_operations *pointer_ops = &ops;
							as_binop *binop = &pointer_ops->binops.entries[pointer_ops->binops.size++];
							binop->op = AS_OPERATOR_APPEND;
							initialize_bin_for_strictypes(self, err, py_value, binop, bin, &static_pool);
						}
					}
					break;
				case AS_OPERATOR_PREPEND:
					if (PyUnicode_Check(py_value)) {
						py_ustr1 = PyUnicode_AsUTF8String(py_value);
						val = PyString_AsString(py_ustr1);
						as_operations_add_prepend_str(&ops, bin, val);
					} else if (PyString_Check(py_value)) {
						val = PyString_AsString(py_value);
						as_operations_add_prepend_str(&ops, bin, val);
					} else if (PyByteArray_Check(py_value)) {
						as_bytes *bytes;
						GET_BYTES_POOL(bytes, &static_pool, err);
						serialize_based_on_serializer_policy(self, SERIALIZER_PYTHON, &bytes, py_value, err);
						as_operations_add_prepend_raw(&ops, bin, bytes->value, bytes->size);
					} else {
						if (!self->strict_types || !strcmp(py_value->ob_type->tp_name, "aerospike.null")) {
							as_operations *pointer_ops = &ops;
							as_binop *binop = &pointer_ops->binops.entries[pointer_ops->binops.size++];
							binop->op = AS_OPERATOR_PREPEND;
							initialize_bin_for_strictypes(self, err, py_value, binop, bin, &static_pool);
						}
					}
					break;
				case AS_OPERATOR_INCR:
					if (PyInt_Check(py_value)) {
						offset = PyInt_AsLong(py_value);
						as_operations_add_incr(&ops, bin, offset);
					} else if ( PyLong_Check(py_value) ) {
						offset = PyLong_AsLong(py_value);
						if (offset == -1 && PyErr_Occurred()) {
							if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
								as_error_update(err, AEROSPIKE_ERR_PARAM, "integer value exceeds sys.maxsize");
								goto CLEANUP;
							}
						}
						as_operations_add_incr(&ops, bin, offset);
					} else if (PyFloat_Check(py_value)) {
						double_offset = PyFloat_AsDouble(py_value);
						as_operations_add_incr_double(&ops, bin, double_offset);
					} else {
						if (!self->strict_types || !strcmp(py_value->ob_type->tp_name, "aerospike.null")) {
							as_operations *pointer_ops = &ops;
							as_binop *binop = &pointer_ops->binops.entries[pointer_ops->binops.size++];
							binop->op = AS_OPERATOR_INCR;
							initialize_bin_for_strictypes(self, err, py_value, binop, bin, &static_pool);
						}
					}
					break;
				case AS_OPERATOR_TOUCH:
                    ops.ttl = 0;
					if (py_value && PyInt_Check(py_value)) {
                        ops.ttl = PyInt_AsLong(py_value);
                    } else if (py_value && PyLong_Check(py_value)) {
                        ttl = PyLong_AsLong(py_value);
                        if((uint32_t)-1 == ttl) {
                            as_error_update(err, AEROSPIKE_ERR_PARAM, "integer value for ttl exceeds sys.maxsize");
                            goto CLEANUP;
                        }
                        ops.ttl = ttl;
                    }
					as_operations_add_touch(&ops);
					break;
				case AS_OPERATOR_READ:
					as_operations_add_read(&ops, bin);
					break;
				case AS_OPERATOR_WRITE:
					pyobject_to_astype_write(self, err, bin, py_value, &put_val, &ops,
							&static_pool, SERIALIZER_PYTHON);
					if (err->code != AEROSPIKE_OK) {
						goto CLEANUP;
					}
					as_operations_add_write(&ops, bin, (as_bin_value *) put_val);
					break;
				default:
					if (self->strict_types) {
						as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid operation given");
						goto CLEANUP;
					}
			}
		}
	}

	// Initialize record
	as_record_init(rec, 0);

	Py_BEGIN_ALLOW_THREADS
	aerospike_key_operate(self->as, err, operate_policy_p, key, &ops, &rec);
	Py_END_ALLOW_THREADS

	if (err->code != AEROSPIKE_OK) {
		as_error_update(err, err->code, NULL);
		goto CLEANUP;
	}
	if(rec) {
		record_to_pyobject(self, err, rec, key, &py_rec);
	}

CLEANUP:
	if (py_ustr) {
		Py_DECREF(py_ustr);
	}
	if (py_ustr1) {
		Py_DECREF(py_ustr1);
	}
	if (rec) {
		as_record_destroy(rec);
	}
	if (key->valuep) {
		as_key_destroy(key);
	}
	if (put_val) {
		as_val_destroy(put_val);
	}

	if ( err->code != AEROSPIKE_OK ) {
		PyObject * py_err = NULL;
		error_to_pyobject(err, &py_err);
		PyObject *exception_type = raise_exception(err);
		PyErr_SetObject(exception_type, py_err);
		Py_DECREF(py_err);
		return NULL;
	}

	if (py_rec) {
		return py_rec;
	} else {
		return PyLong_FromLong(0);
	}
}
AerospikeQuery * AerospikeQuery_Select(AerospikeQuery * self, PyObject * args, PyObject * kwds)
{
	TRACE();

	int nbins = (int) PyTuple_Size(args);
	char * bin = NULL;
	PyObject * py_ubin = NULL;
	as_error err;
	as_error_init(&err);

	if (!self || !self->client->as) {
		as_error_update(&err, AEROSPIKE_ERR_PARAM, "Invalid aerospike object");
		goto CLEANUP;
	}

	if (!self->client->is_conn_16) {
		as_error_update(&err, AEROSPIKE_ERR_CLUSTER, "No connection to aerospike cluster");
		goto CLEANUP;
	}

	as_query_select_init(&self->query, nbins);

	for ( int i = 0; i < nbins; i++ ) {
		PyObject * py_bin = PyTuple_GetItem(args, i);
		if (PyUnicode_Check(py_bin)){
			py_ubin = PyUnicode_AsUTF8String(py_bin);
			bin = PyBytes_AsString(py_ubin);
		}
		else if (PyString_Check(py_bin)) {
			// TRACE();
			bin = PyString_AsString(py_bin);
		} else if (PyByteArray_Check(py_bin)) {
			bin = PyByteArray_AsString(py_bin);
		} else {
			// TRACE();
			as_error_update(&err, AEROSPIKE_ERR_PARAM, "Bin name should be of type string");
			PyObject * py_err = NULL;
			error_to_pyobject(&err, &py_err);
			PyObject *exception_type = raise_exception(&err);
			PyErr_SetObject(exception_type, py_err);
			Py_DECREF(py_err);
			return NULL;
		}

		as_query_select(&self->query, bin);

		if (py_ubin){
			Py_DECREF(py_ubin);
			py_ubin = NULL;
		}
	}

CLEANUP:
	if (err.code != AEROSPIKE_OK) {
		PyObject * py_err = NULL;
		error_to_pyobject(&err, &py_err);
		PyObject *exception_type = raise_exception(&err);
		PyErr_SetObject(exception_type, py_err);
		Py_DECREF(py_err);
		return NULL;
	}

	Py_INCREF(self);
	return self;
}
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;
}