Exemplo n.º 1
0
static PyObject* Cache_iterstore(Cache* self, PyObject *args, PyObject *kwds)
{
    PyObject *addrs;
    unsigned int length = 1;
    
    static char *kwlist[] = {"addrs", "length", NULL};
    PyArg_ParseTupleAndKeywords(args, kwds, "O|I", kwlist, &addrs, &length);
    
    // Get and check iterator
    PyObject *addrs_iter = PyObject_GetIter(addrs);
    if(addrs_iter == NULL) {
        PyErr_SetString(PyExc_ValueError, "addrs is not iteratable");
        return NULL;
    }
    
    // Iterate of elements in addrs
    PyObject *addr;
    while((addr = PyIter_Next(addrs_iter))) {
        // Each address is expanded to a certain length (default is 1)
        for(int i=0; i<length; i++) {
#if PY_MAJOR_VERSION >= 3
            Cache__store(self, PyLong_AsUnsignedLongMask(addr)+i);
#else
            Cache__store(self, PyLong_AsUnsignedLongMask(addr)+i);
#endif
        }
        Py_DECREF(addr);
    }
    Py_DECREF(addrs_iter);
    Py_RETURN_NONE;
}
Exemplo n.º 2
0
static PyObject *
P_set(void *ptr, PyObject *value, Py_ssize_t size)
{
    void *v;
    if (value == Py_None) {
        *(void **)ptr = NULL;
        _RET(value);
    }

    if (!PyLong_Check(value) && !PyLong_Check(value)) {
        PyErr_SetString(PyExc_TypeError,
                        "cannot be converted to pointer");
        return NULL;
    }

#if SIZEOF_VOID_P <= SIZEOF_LONG
    v = (void *)PyLong_AsUnsignedLongMask(value);
#else
#ifndef HAVE_LONG_LONG
#   error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long"
#elif SIZEOF_LONG_LONG < SIZEOF_VOID_P
#   error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)"
#endif
    v = (void *)PyLong_AsUnsignedLongLongMask(value);
#endif

    if (PyErr_Occurred())
        return NULL;

    *(void **)ptr = v;
    _RET(value);
}
Exemplo n.º 3
0
static PyObject *
z_set(void *ptr, PyObject *value, Py_ssize_t size)
{
    if (value == Py_None) {
        *(char **)ptr = NULL;
        Py_INCREF(value);
        return value;
    }
    if (PyBytes_Check(value)) {
        *(char **)ptr = PyBytes_AsString(value);
        Py_INCREF(value);
        return value;
    } else if (PyLong_Check(value)) {
#if SIZEOF_VOID_P == SIZEOF_LONG_LONG
        *(char **)ptr = (char *)PyLong_AsUnsignedLongLongMask(value);
#else
        *(char **)ptr = (char *)PyLong_AsUnsignedLongMask(value);
#endif
        _RET(value);
    }
    PyErr_Format(PyExc_TypeError,
                 "string or integer address expected instead of %s instance",
                 value->ob_type->tp_name);
    return NULL;
}
Exemplo n.º 4
0
static PyObject *
Z_set(void *ptr, PyObject *value, Py_ssize_t size)
{
    if (value == Py_None) {
        *(wchar_t **)ptr = NULL;
        Py_INCREF(value);
        return value;
    }
    if (PyLong_Check(value) || PyLong_Check(value)) {
#if SIZEOF_VOID_P == SIZEOF_LONG_LONG
        *(wchar_t **)ptr = (wchar_t *)PyLong_AsUnsignedLongLongMask(value);
#else
        *(wchar_t **)ptr = (wchar_t *)PyLong_AsUnsignedLongMask(value);
#endif
        Py_INCREF(Py_None);
        return Py_None;
    }
    if (!PyUnicode_Check(value)) {
        PyErr_Format(PyExc_TypeError,
                     "unicode string or integer address expected instead of %s instance",
                     value->ob_type->tp_name);
        return NULL;
    } else
        Py_INCREF(value);
#if Py_UNICODE_SIZE == SIZEOF_WCHAR_T
    /* We can copy directly.  Hm, are unicode objects always NUL
       terminated in Python, internally?
     */
    *(wchar_t **)ptr = (wchar_t *) PyUnicode_AS_UNICODE(value);
    return value;
#else
    {
        /* We must create a wchar_t* buffer from the unicode object,
           and keep it alive */
        PyObject *keep;
        wchar_t *buffer;

        buffer = PyUnicode_AsWideCharString(value, NULL);
        if (!buffer) {
            Py_DECREF(value);
            return NULL;
        }
        keep = PyCapsule_New(buffer, CTYPES_CFIELD_CAPSULE_NAME_PYMEM, pymem_destructor);
        if (!keep) {
            Py_DECREF(value);
            PyMem_Free(buffer);
            return NULL;
        }
        *(wchar_t **)ptr = (wchar_t *)buffer;
        Py_DECREF(value);
        return keep;
    }
#endif
}
Exemplo n.º 5
0
STDMETHODIMP PyGExplorerCommand::GetFlags(
		/* [out] */ EXPCMDFLAGS * pFlags)
{
	PY_GATEWAY_METHOD;
	PyObject *result;
	HRESULT hr=InvokeViaPolicy("GetFlags", &result);
	if (FAILED(hr)) return hr;
	// Process the Python results, and convert back to the real params
	*pFlags = PyLong_AsUnsignedLongMask(result);
	hr = PyCom_SetAndLogCOMErrorFromPyException("GetFlags", IID_IExplorerCommand);
	Py_DECREF(result);
	return hr;
}
Exemplo n.º 6
0
STDMETHODIMP PyGShellItem::GetAttributes(
		/* [in] */ SFGAOF sfgaoMask,
		/* [out] */ SFGAOF * psfgaoAttribs)
{
	PY_GATEWAY_METHOD;
	PyObject *result;
	HRESULT hr=InvokeViaPolicy("GetAttributes", &result, "k", sfgaoMask);
	if (FAILED(hr)) return hr;
	// Process the Python results, and convert back to the real params
	*psfgaoAttribs = PyLong_AsUnsignedLongMask(result);
	hr = PyCom_SetAndLogCOMErrorFromPyException("GetAttributes", IID_IShellItem);
	Py_DECREF(result);
	return hr;
}
Exemplo n.º 7
0
STDMETHODIMP PyGShellItemArray::GetAttributes(
		/* [in] */ SIATTRIBFLAGS dwAttribFlags,
		/* [in] */ SFGAOF sfgaoMask,
		/* [out] */ SFGAOF * psfgaoAttribs)
{
	PY_GATEWAY_METHOD;
	PyObject *result;
	HRESULT hr=InvokeViaPolicy("GetAttributes", &result, "kk", dwAttribFlags, sfgaoMask);
	if (FAILED(hr)) return hr;
	*psfgaoAttribs = PyLong_AsUnsignedLongMask(result);
	hr = PyCom_SetAndLogCOMErrorFromPyException("GetAttributes", IID_IShellItemArray);
	Py_DECREF(result);
	return hr;

}
Exemplo n.º 8
0
static int
get_ulong(PyObject *v, unsigned long *p)
{
    unsigned long x;

    if (PyFloat_Check(v)) {
        PyErr_SetString(PyExc_TypeError,
                        "int expected instead of float");
        return -1;
    }
    x = PyLong_AsUnsignedLongMask(v);
    if (x == (unsigned long)-1 && PyErr_Occurred())
        return -1;
    *p = x;
    return 0;
}
Exemplo n.º 9
0
STDMETHODIMP PyGExplorerCommand::GetState(
		/* [in] */ IShellItemArray * psiItemArray,
		/* [in] */ BOOL fOkToBeSlow,
		/* [out] */ EXPCMDSTATE * pCmdState)
{
	PY_GATEWAY_METHOD;
	PyObject *obpsiItemArray;
	obpsiItemArray = PyCom_PyObjectFromIUnknown(psiItemArray, IID_IShellItemArray, TRUE);
	PyObject *result;
	HRESULT hr=InvokeViaPolicy("GetState", &result, "Oi", obpsiItemArray, fOkToBeSlow);
	Py_XDECREF(obpsiItemArray);
	if (FAILED(hr)) return hr;
	// Process the Python results, and convert back to the real params
	*pCmdState = PyLong_AsUnsignedLongMask(result);
	hr = PyCom_SetAndLogCOMErrorFromPyException("GetState", IID_IExplorerCommand);
	Py_DECREF(result);
	return hr;
}
Exemplo n.º 10
0
bool py_to_color(PyObject *o, SproxelColor &c)
{
  if (PyInt_Check(o) || PyLong_Check(o))
  {
    unsigned i=PyInt_AsUnsignedLongMask(o);
    if (PyErr_Occurred())
    {
      PyErr_Clear();
      i=PyLong_AsUnsignedLongMask(o);
      if (PyErr_Occurred()) return false;
    }
    if ((i&0xFF000000)==0 && i!=0) i|=0xFF000000;
    c.a=((i>>24)&0xFF)/255.0f;
    c.r=((i>>16)&0xFF)/255.0f;
    c.g=((i>> 8)&0xFF)/255.0f;
    c.b=((i    )&0xFF)/255.0f;
    return true;
  }
Exemplo n.º 11
0
static PyObject *
Z_set(void *ptr, PyObject *value, Py_ssize_t size)
{
    PyObject *keep;
    wchar_t *buffer;

    if (value == Py_None) {
        *(wchar_t **)ptr = NULL;
        Py_INCREF(value);
        return value;
    }
    if (PyLong_Check(value) || PyLong_Check(value)) {
#if SIZEOF_VOID_P == SIZEOF_LONG_LONG
        *(wchar_t **)ptr = (wchar_t *)PyLong_AsUnsignedLongLongMask(value);
#else
        *(wchar_t **)ptr = (wchar_t *)PyLong_AsUnsignedLongMask(value);
#endif
        Py_INCREF(Py_None);
        return Py_None;
    }
    if (!PyUnicode_Check(value)) {
        PyErr_Format(PyExc_TypeError,
                     "unicode string or integer address expected instead of %s instance",
                     value->ob_type->tp_name);
        return NULL;
    }

    /* We must create a wchar_t* buffer from the unicode object,
       and keep it alive */
    buffer = PyUnicode_AsWideCharString(value, NULL);
    if (!buffer)
        return NULL;
    keep = PyCapsule_New(buffer, CTYPES_CFIELD_CAPSULE_NAME_PYMEM, pymem_destructor);
    if (!keep) {
        PyMem_Free(buffer);
        return NULL;
    }
    *(wchar_t **)ptr = buffer;
    return keep;
}
Exemplo n.º 12
0
static PyObject* Cache_loadstore(Cache* self, PyObject *args, PyObject *kwds)
{
    PyObject *addrs;
    unsigned int length = 1;
    int write_allocate = 1; 
    
    static char *kwlist[] = {"addrs", "length", "write_allocate", NULL};
    PyArg_ParseTupleAndKeywords(args, kwds, "O|Ii", kwlist, &addrs, &length, &write_allocate);
    
    // Get and check iterator
    PyObject *addrs_iter = PyObject_GetIter(addrs);
    if(addrs_iter == NULL) {
        PyErr_SetString(PyExc_ValueError, "addrs is not iteratable");
        return NULL;
    }
    
    // Iterate of elements in addrs
    PyObject *loadstore_item, *load_addrs, *store_addrs, *addr, *load_iter, *store_iter;
    while((loadstore_item = PyIter_Next(addrs_iter))) {
        if(!PySequence_Check(loadstore_item)) {
            PyErr_SetString(PyExc_ValueError, "addrs element does not provide a sequence protocol");
            return NULL;
        }
        // PySys_WriteStdout("LENGTH=%i\n", PySequence_Length(loadstore_item));
        if(PySequence_Length(loadstore_item) != 2){
            PyErr_SetString(PyExc_ValueError, "each addrs element needs exactly two elements");
            return NULL;
        }
        load_addrs = PySequence_GetItem(loadstore_item, 0);
        store_addrs = PySequence_GetItem(loadstore_item, 1);
        
        // Unless None (otherwise ignore loads)
        if(load_addrs != Py_None) {
            if(!PySequence_Check(load_addrs)) {
                PyErr_SetString(
                    PyExc_ValueError, "load element does not provide a sequence protocol");
                return NULL;
            }

            // FIXME maybe this is better: Pass along to iterstore
            //Cache_iterstore(self, store_addrs, length)
            
            // Iterate of elements in load_addrs
            load_iter = PyObject_GetIter(load_addrs);
            if(load_iter == NULL) {
                PyErr_SetString(PyExc_ValueError, "load address is not iteratable");
                return NULL;
            }
            while((addr = PyIter_Next(load_iter))) {
                // Each address is expanded to a certain length (default is 1)
                for(int i=0; i<length; i++) {
#if PY_MAJOR_VERSION >= 3
                    Cache__load(self, PyLong_AsUnsignedLongMask(addr)+i);
#else
                    Cache__load(self, PyLong_AsUnsignedLongMask(addr)+i);
#endif
                }
                Py_DECREF(addr);
            }
        }
        
        // Unless None (ortherwise ignore stores)
        
        if(store_addrs != Py_None) {
            if(!PySequence_Check(store_addrs)) {
                PyErr_SetString(
                    PyExc_ValueError, "store element does not provide a sequence protocol");
                return NULL;
            }
            
            // FIXME maybe this is better: Pass along to iterstore
            //Cache_iterload(self, load_addrs, length)
            
            // Iterate of elements in store_addrs
            store_iter = PyObject_GetIter(store_addrs);
            if(store_iter == NULL) {
                PyErr_SetString(PyExc_ValueError, "store address is not iteratable");
                return NULL;
            }
            while((addr = PyIter_Next(store_iter))) {
                // Each address is expanded to a certain length (default is 1)
                for(int i=0; i<length; i++) {
                    // Handle write-allocate
                    if(write_allocate) {
#if PY_MAJOR_VERSION >= 3
                        Cache__load(self, PyLong_AsUnsignedLongMask(addr)+i);
#else
                        Cache__load(self, PyLong_AsUnsignedLongMask(addr)+i);
#endif
                    }
#if PY_MAJOR_VERSION >= 3
                    Cache__store(self, PyLong_AsUnsignedLongMask(addr)+i);
#else
                    Cache__store(self, PyLong_AsUnsignedLongMask(addr)+i);
#endif
                }
                Py_DECREF(addr);
            }
        }
        
        Py_DECREF(load_addrs);
        Py_DECREF(store_addrs);
        Py_DECREF(loadstore_item);
    }
    Py_DECREF(addrs_iter);
    Py_RETURN_NONE;
}
Exemplo n.º 13
0
static int convertTo_QVector_1900(PyObject *sipPy,void **sipCppPtrV,int *sipIsErr,PyObject *sipTransferObj)
{
    QVector<GLuint> **sipCppPtr = reinterpret_cast<QVector<GLuint> **>(sipCppPtrV);

#line 54 "C:\\Users\\marcus\\Downloads\\PyQt-gpl-5.4\\PyQt-gpl-5.4\\sip/QtGui/qpygui_qvector.sip"
    PyObject *iter = PyObject_GetIter(sipPy);

    if (!sipIsErr)
    {
        Py_XDECREF(iter);

        return (iter
#if PY_MAJOR_VERSION < 3
                && !PyString_Check(sipPy)
#endif
                && !PyUnicode_Check(sipPy));
    }

    if (!iter)
    {
        *sipIsErr = 1;

        return 0;
    }

    QVector<unsigned> *qv = new QVector<unsigned>;

    for (SIP_SSIZE_T i = 0; ; ++i)
    {
        PyErr_Clear();
        PyObject *itm = PyIter_Next(iter);

        if (!itm)
        {
            if (PyErr_Occurred())
            {
                delete qv;
                Py_DECREF(iter);
                *sipIsErr = 1;

                return 0;
            }

            break;
        }

        PyErr_Clear();
        unsigned long val = PyLong_AsUnsignedLongMask(itm);

        if (PyErr_Occurred())
        {
            PyErr_Format(PyExc_TypeError,
                    "index " SIP_SSIZE_T_FORMAT " has type '%s' but 'int' is expected",
                    i, Py_TYPE(itm)->tp_name);

            Py_DECREF(itm);
            delete qv;
            Py_DECREF(iter);
            *sipIsErr = 1;

            return 0;
        }

        qv->append(val);

        Py_DECREF(itm);
    }

    Py_DECREF(iter);

    *sipCppPtr = qv;

    return sipGetState(sipTransferObj);
#line 137 "C:\\Users\\marcus\\Downloads\\PyQt-gpl-5.4\\PyQt-gpl-5.4\\QtGui/sipQtGuiQVector1900.cpp"
}
Exemplo n.º 14
0
static PyObject *qdbusargument_add(QDBusArgument *arg, PyObject *obj, int mtype)
{
    int iserr = 0;

    if (PyLong_CheckExact(obj)
#if PY_MAJOR_VERSION < 3
            || PyInt_CheckExact(obj)
#endif
            )
    {
        if (mtype == QMetaType::UChar || mtype == QMetaType::UShort || mtype == QMetaType::UInt || mtype == QMetaType::ULongLong)
        {
            // Handle the unsigned values.
#if defined(HAVE_LONG_LONG)
            unsigned PY_LONG_LONG v = PyLong_AsUnsignedLongLongMask(obj);
#else
            unsigned long v = PyLong_AsUnsignedLongMask(obj);
#endif

            switch (mtype)
            {
            case QMetaType::UChar:
                *arg << (uchar)v;
                break;

            case QMetaType::UShort:
                *arg << (ushort)v;
                break;

            case QMetaType::UInt:
                *arg << (uint)v;
                break;

            case QMetaType::ULongLong:
                *arg << (qulonglong)v;
                break;
            }
        }
        else if (mtype == QMetaType::Short || mtype == QMetaType::Int || mtype == QMetaType::LongLong)
        {
            // Handle the signed values.
#if defined(HAVE_LONG_LONG)
            PY_LONG_LONG v = PyLong_AsLongLong(obj);
#else
            long v = PyLong_AsLong(obj);
#endif

            switch (mtype)
            {
            case QMetaType::Short:
                *arg << (short)v;
                break;

            case QMetaType::Int:
                *arg << (int)v;
                break;

            case QMetaType::LongLong:
                *arg << (qlonglong)v;
                break;
            }
        }
        else
        {
            PyErr_Format(PyExc_ValueError,
                    "%d is an invalid QMetaType::Type for an interger object",
                    mtype);
            iserr = 1;
        }
    }
    else if (mtype == QMetaType::QStringList)
    {
        // A QStringList has to be handled explicitly to prevent it being seen
        // as a vialiant list.

        int value_state;

        QStringList *qsl = reinterpret_cast<QStringList *>(
                sipForceConvertToType(obj, sipType_QStringList, 0,
                        SIP_NOT_NONE, &value_state, &iserr));

        if (!iserr)
        {
            arg->beginArray(QMetaType::QString);

            for (int i = 0; i < qsl->count(); ++i)
                *arg << qsl->at(i);

            arg->endArray();

            sipReleaseType(qsl, sipType_QStringList, value_state);
        }
    }
    else
    {
        int value_state;

        QVariant *qv = reinterpret_cast<QVariant *>(
                sipForceConvertToType(obj, sipType_QVariant, 0, SIP_NOT_NONE,
                        &value_state, &iserr));

        if (!iserr)
        {
            // This is an internal method. If it proves to be a problem then we
            // will have to handle each type explicitly.
            arg->appendVariant(*qv);
            sipReleaseType(qv, sipType_QVariant, value_state);
        }
    }

    if (iserr)
        return 0;

    Py_INCREF(Py_None);
    return Py_None;
}
Exemplo n.º 15
0
static char *
convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf,
	      size_t bufsize, PyObject **freelist)
{
	char *format = *p_format;
	char c = *format++;
#ifdef Py_USING_UNICODE
	PyObject *uarg;
#endif
	
	switch (c) {
	
	case 'b': { /* unsigned byte -- very short int */
		char *p = va_arg(*p_va, char *);
		long ival;
		if (float_argument_error(arg))
			return converterr("integer<b>", arg, msgbuf, bufsize);
		ival = PyInt_AsLong(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<b>", arg, msgbuf, bufsize);
		else if (ival < 0) {
			PyErr_SetString(PyExc_OverflowError,
			"unsigned byte integer is less than minimum");
			return converterr("integer<b>", arg, msgbuf, bufsize);
		}
		else if (ival > UCHAR_MAX) {
			PyErr_SetString(PyExc_OverflowError,
			"unsigned byte integer is greater than maximum");
			return converterr("integer<b>", arg, msgbuf, bufsize);
		}
		else
			*p = (unsigned char) ival;
		break;
	}
	
	case 'B': {/* byte sized bitfield - both signed and unsigned
		      values allowed */  
		char *p = va_arg(*p_va, char *);
		long ival;
		if (float_argument_error(arg))
			return converterr("integer<B>", arg, msgbuf, bufsize);
		ival = PyInt_AsUnsignedLongMask(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<B>", arg, msgbuf, bufsize);
		else
			*p = (unsigned char) ival;
		break;
	}
	
	case 'h': {/* signed short int */
		short *p = va_arg(*p_va, short *);
		long ival;
		if (float_argument_error(arg))
			return converterr("integer<h>", arg, msgbuf, bufsize);
		ival = PyInt_AsLong(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<h>", arg, msgbuf, bufsize);
		else if (ival < SHRT_MIN) {
			PyErr_SetString(PyExc_OverflowError,
			"signed short integer is less than minimum");
			return converterr("integer<h>", arg, msgbuf, bufsize);
		}
		else if (ival > SHRT_MAX) {
			PyErr_SetString(PyExc_OverflowError,
			"signed short integer is greater than maximum");
			return converterr("integer<h>", arg, msgbuf, bufsize);
		}
		else
			*p = (short) ival;
		break;
	}
	
	case 'H': { /* short int sized bitfield, both signed and
		       unsigned allowed */ 
		unsigned short *p = va_arg(*p_va, unsigned short *);
		long ival;
		if (float_argument_error(arg))
			return converterr("integer<H>", arg, msgbuf, bufsize);
		ival = PyInt_AsUnsignedLongMask(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<H>", arg, msgbuf, bufsize);
		else
			*p = (unsigned short) ival;
		break;
	}
	
	case 'i': {/* signed int */
		int *p = va_arg(*p_va, int *);
		long ival;
		if (float_argument_error(arg))
			return converterr("integer<i>", arg, msgbuf, bufsize);
		ival = PyInt_AsLong(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<i>", arg, msgbuf, bufsize);
		else if (ival > INT_MAX) {
			PyErr_SetString(PyExc_OverflowError,
				"signed integer is greater than maximum");
			return converterr("integer<i>", arg, msgbuf, bufsize);
		}
		else if (ival < INT_MIN) {
			PyErr_SetString(PyExc_OverflowError,
				"signed integer is less than minimum");
			return converterr("integer<i>", arg, msgbuf, bufsize);
		}
		else
			*p = ival;
		break;
	}

	case 'I': { /* int sized bitfield, both signed and
		       unsigned allowed */ 
		unsigned int *p = va_arg(*p_va, unsigned int *);
		unsigned int ival;
		if (float_argument_error(arg))
			return converterr("integer<I>", arg, msgbuf, bufsize);
		ival = PyInt_AsUnsignedLongMask(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<I>", arg, msgbuf, bufsize);
		else
			*p = ival;
		break;
	}
	
	case 'l': {/* long int */
		long *p = va_arg(*p_va, long *);
		long ival;
		if (float_argument_error(arg))
			return converterr("integer<l>", arg, msgbuf, bufsize);
		ival = PyInt_AsLong(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<l>", arg, msgbuf, bufsize);
		else
			*p = ival;
		break;
	}

	case 'k': { /* long sized bitfield */
		unsigned long *p = va_arg(*p_va, unsigned long *);
		unsigned long ival;
		if (PyInt_Check(arg))
			ival = PyInt_AsUnsignedLongMask(arg);
		else if (PyLong_Check(arg))
			ival = PyLong_AsUnsignedLongMask(arg);
		else
			return converterr("integer<k>", arg, msgbuf, bufsize);
		*p = ival;
		break;
	}
	
#ifdef HAVE_LONG_LONG
	case 'L': {/* PY_LONG_LONG */
		PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * );
		PY_LONG_LONG ival = PyLong_AsLongLong( arg );
		if( ival == (PY_LONG_LONG)-1 && PyErr_Occurred() ) {
			return converterr("long<L>", arg, msgbuf, bufsize);
		} else {
			*p = ival;
		}
		break;
	}

	case 'K': { /* long long sized bitfield */
		unsigned PY_LONG_LONG *p = va_arg(*p_va, unsigned PY_LONG_LONG *);
		unsigned PY_LONG_LONG ival;
		if (PyInt_Check(arg))
			ival = PyInt_AsUnsignedLongMask(arg);
		else if (PyLong_Check(arg))
			ival = PyLong_AsUnsignedLongLongMask(arg);
		else
			return converterr("integer<K>", arg, msgbuf, bufsize);
		*p = ival;
		break;
	}
#endif
	
	case 'f': {/* float */
		float *p = va_arg(*p_va, float *);
		double dval = PyFloat_AsDouble(arg);
		if (PyErr_Occurred())
			return converterr("float<f>", arg, msgbuf, bufsize);
		else
			*p = (float) dval;
		break;
	}
	
	case 'd': {/* double */
		double *p = va_arg(*p_va, double *);
		double dval = PyFloat_AsDouble(arg);
		if (PyErr_Occurred())
			return converterr("float<d>", arg, msgbuf, bufsize);
		else
			*p = dval;
		break;
	}
	
#ifndef WITHOUT_COMPLEX
	case 'D': {/* complex double */
		Py_complex *p = va_arg(*p_va, Py_complex *);
		Py_complex cval;
		cval = PyComplex_AsCComplex(arg);
		if (PyErr_Occurred())
			return converterr("complex<D>", arg, msgbuf, bufsize);
		else
			*p = cval;
		break;
	}
#endif /* WITHOUT_COMPLEX */
	
	case 'c': {/* char */
		char *p = va_arg(*p_va, char *);
		if (PyString_Check(arg) && PyString_Size(arg) == 1)
			*p = PyString_AS_STRING(arg)[0];
		else
			return converterr("char", arg, msgbuf, bufsize);
		break;
	}
	
	case 's': {/* string */
		if (*format == '#') {
			void **p = (void **)va_arg(*p_va, char **);
			int *q = va_arg(*p_va, int *);
			
			if (PyString_Check(arg)) {
				*p = PyString_AS_STRING(arg);
				*q = PyString_GET_SIZE(arg);
			}
#ifdef Py_USING_UNICODE
			else if (PyUnicode_Check(arg)) {
				uarg = UNICODE_DEFAULT_ENCODING(arg);
				if (uarg == NULL)
					return converterr(CONV_UNICODE,
							  arg, msgbuf, bufsize);
				*p = PyString_AS_STRING(uarg);
				*q = PyString_GET_SIZE(uarg);
			}
#endif
			else { /* any buffer-like object */
				char *buf;
				int count = convertbuffer(arg, p, &buf);
				if (count < 0)
					return converterr(buf, arg, msgbuf, bufsize);
				*q = count;
			}
			format++;
		} else {
			char **p = va_arg(*p_va, char **);
			
			if (PyString_Check(arg))
				*p = PyString_AS_STRING(arg);
#ifdef Py_USING_UNICODE
			else if (PyUnicode_Check(arg)) {
				uarg = UNICODE_DEFAULT_ENCODING(arg);
				if (uarg == NULL)
					return converterr(CONV_UNICODE,
							  arg, msgbuf, bufsize);
				*p = PyString_AS_STRING(uarg);
			}
#endif
			else
				return converterr("string", arg, msgbuf, bufsize);
			if ((int)strlen(*p) != PyString_Size(arg))
				return converterr("string without null bytes",
						  arg, msgbuf, bufsize);
		}
		break;
	}
Exemplo n.º 16
0
static PyObject *
osk_struts_set (PyObject *self, PyObject *args)
{
    Display       *dpy;
    unsigned long  xid;
    unsigned long  struts[12] = { 0, };
    PyObject      *obj, *seq, **items;
    int            i;

    if (!PyArg_ParseTuple (args, "kO", &xid, &obj))
        return NULL;

    seq = PySequence_Fast (obj, "expected sequence type");
    if (!seq)
        return NULL;

    if (PySequence_Fast_GET_SIZE (seq) != 12)
    {
        PyErr_SetString (PyExc_ValueError, "expected 12 values");
        return NULL;
    }

    items = PySequence_Fast_ITEMS (seq);

    for (i = 0; i < 12; i++, items++)
    {
        struts[i] = PyLong_AsUnsignedLongMask (*items);

        if (PyErr_Occurred ())
        {
            Py_DECREF (seq);
            return NULL;
        }

        if (struts[i] < 0)
        {
            PyErr_SetString (PyExc_ValueError, "expected value >= 0");
            Py_DECREF (seq);
            return NULL;
        }
    }

    Py_DECREF (seq);

    dpy = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());

    gdk_error_trap_push ();

    XChangeProperty (dpy, xid,
                     XInternAtom (dpy, "_NET_WM_STRUT", False),
                     XA_CARDINAL, 32, PropModeReplace,
                     (unsigned char *) &struts, 4);

    XChangeProperty (dpy, xid,
                     XInternAtom (dpy, "_NET_WM_STRUT_PARTIAL", False),
                     XA_CARDINAL, 32, PropModeReplace,
                     (unsigned char *) &struts, 12);


    gdk_error_trap_pop_ignored ();

    Py_RETURN_NONE;
}
Exemplo n.º 17
0
PyObject *
SharedMemory_write(SharedMemory *self, PyObject *args, PyObject *kw) {
    /* See comments for read() regarding "size issues". Note that here
       Python provides the byte_count so it can't be negative.

       In Python >= 2.5, the Python argument specifier 's#' expects a
       py_ssize_t for its second parameter. A long is long enough. It might
       be too big, though, on platforms where a long is larger than
       py_ssize_t. Therefore I *must* initialize it to 0 so that whatever
       Python doesn't write to is zeroed out.
   */
    unsigned long offset = 0;
    unsigned long size;
    PyObject *py_size;
    char *keyword_list[ ] = {"s", "offset", NULL};
#if PY_MAJOR_VERSION > 2
    static char args_format[] = "s*|k";
    Py_buffer data;
#else
    static char args_format[] = "s#|k";
    typedef struct {
        const char *buf;
        long len;
    } MyBuffer;
    MyBuffer data;
    data.len = 0;
#endif

    if (self->read_only) {
        PyErr_SetString(PyExc_OSError, "Write attempt on read-only memory segment");
        goto error_return;
    }

    if (!PyArg_ParseTupleAndKeywords(args, kw, args_format, keyword_list,
#if PY_MAJOR_VERSION > 2
                          &data,
#else
                          &(data.buf), &(data.len),
#endif
                          &offset))
        goto error_return;

    if (self->address == NULL) {
        PyErr_SetString(pNotAttachedException, "Write attempt on unattached memory segment");
        goto error_return;
    }

    if ( (py_size = shm_get_value(self->id, SVIFP_SHM_SIZE)) ) {
#if PY_MAJOR_VERSION > 2
        size = PyLong_AsUnsignedLongMask(py_size);
#else
        size = PyInt_AsUnsignedLongMask(py_size);
#endif
        Py_DECREF(py_size);
    }
    else
        goto error_return;

    DPRINTF("write size check; size=%lu, offset=%lu, dat.len=%ld\n",
            size, offset, data.len);

    // Remember that offset and size are both ulongs, so size > offset, then
    // size - offset (as in the second part of the if expression) will evaluate
    // to a "negative" number which is a very large ulong.
    if ((offset > size) || ((unsigned long)data.len > size - offset)) {
        PyErr_SetString(PyExc_ValueError, "Attempt to write past end of memory segment");
        goto error_return;
    }

    memcpy((self->address + offset), data.buf, data.len);

    Py_RETURN_NONE;

    error_return:
    return NULL;
}
Exemplo n.º 18
0
PyObject *
SharedMemory_read(SharedMemory *self, PyObject *args, PyObject *keywords) {
    /* Tricky business here. A memory segment's size is a size_t which is
       ulong or smaller. However, the largest string that Python can
       construct is of ssize_t which is long or smaller. Therefore, the
       size and offset variables must be ulongs while the byte_count
       must be a long (and must not exceed LONG_MAX).
       Mind your math!
    */
    long byte_count = 0;
    unsigned long offset = 0;
    unsigned long size;
    PyObject *py_size;
    char *keyword_list[ ] = {"byte_count", "offset", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, keywords, "|lk", keyword_list,
                                     &byte_count, &offset))
        goto error_return;

    if (self->address == NULL) {
        PyErr_SetString(pNotAttachedException,
                        "Read attempt on unattached memory segment");
        goto error_return;
    }

    if ( (py_size = shm_get_value(self->id, SVIFP_SHM_SIZE)) ) {
#if PY_MAJOR_VERSION > 2
        size = PyLong_AsUnsignedLongMask(py_size);
#else
        size = PyInt_AsUnsignedLongMask(py_size);
#endif
        Py_DECREF(py_size);
    }
    else
        goto error_return;

    DPRINTF("offset = %lu, byte_count = %ld, size = %lu\n",
            offset, byte_count, size);

    if (offset >= size) {
        PyErr_SetString(PyExc_ValueError, "The offset must be less than the segment size");
        goto error_return;
    }

    if (byte_count < 0) {
        PyErr_SetString(PyExc_ValueError, "The byte_count cannot be negative");
        goto error_return;
    }

    /* If the caller didn't specify a byte count or specified one that would
       read past the end of the segment, return everything from the offset to
       the end of the segment.
       Be careful here not to express the second if condition w/addition, e.g.
            (byte_count + offset > size)
       It might be more intuitive but since byte_count is a long and offset
       is a ulong, their sum could cause an arithmetic overflow. */
    if ((!byte_count) || ((unsigned long)byte_count > size - offset)) {
        // byte_count needs to be calculated
        if (size - offset <= (unsigned long)PY_STRING_LENGTH_MAX)
            byte_count = size - offset;
        else {
            // Caller is asking for more bytes than I can stuff into
            // a Python string.
            PyErr_Format(PyExc_ValueError,
                         "The byte_count cannot exceed Python's max string length %ld",
                         (long)PY_STRING_LENGTH_MAX);
            goto error_return;
        }
    }


#if PY_MAJOR_VERSION > 2
    return PyBytes_FromStringAndSize(self->address + offset, byte_count);
#else
    return PyString_FromStringAndSize(self->address + offset, byte_count);
#endif

    error_return:
    return NULL;
}
Exemplo n.º 19
0
static PyObject *
Z_set(void *ptr, PyObject *value, Py_ssize_t size)
{
    if (value == Py_None) {
        *(wchar_t **)ptr = NULL;
        Py_INCREF(value);
        return value;
    }
    if (PyLong_Check(value) || PyLong_Check(value)) {
#if SIZEOF_VOID_P == SIZEOF_LONG_LONG
        *(wchar_t **)ptr = (wchar_t *)PyLong_AsUnsignedLongLongMask(value);
#else
        *(wchar_t **)ptr = (wchar_t *)PyLong_AsUnsignedLongMask(value);
#endif
        Py_INCREF(Py_None);
        return Py_None;
    }
    if (PyBytes_Check(value)) {
        value = PyUnicode_FromEncodedObject(value,
                                            _ctypes_conversion_encoding,
                                            _ctypes_conversion_errors);
        if (!value)
            return NULL;
    } else if (!PyUnicode_Check(value)) {
        PyErr_Format(PyExc_TypeError,
                     "unicode string or integer address expected instead of %s instance",
                     value->ob_type->tp_name);
        return NULL;
    } else
        Py_INCREF(value);
#ifdef HAVE_USABLE_WCHAR_T
    /* HAVE_USABLE_WCHAR_T means that Py_UNICODE and wchar_t is the same
       type.  So we can copy directly.  Hm, are unicode objects always NUL
       terminated in Python, internally?
     */
    *(wchar_t **)ptr = PyUnicode_AS_UNICODE(value);
    return value;
#else
    {
        /* We must create a wchar_t* buffer from the unicode object,
           and keep it alive */
        PyObject *keep;
        wchar_t *buffer;

        int size = PyUnicode_GET_SIZE(value);
        size += 1; /* terminating NUL */
        size *= sizeof(wchar_t);
        buffer = (wchar_t *)PyMem_Malloc(size);
        if (!buffer) {
            Py_DECREF(value);
            return PyErr_NoMemory();
        }
        memset(buffer, 0, size);
        keep = PyCapsule_New(buffer, CTYPES_CFIELD_CAPSULE_NAME_PYMEM, pymem_destructor);
        if (!keep) {
            Py_DECREF(value);
            PyMem_Free(buffer);
            return NULL;
        }
        *(wchar_t **)ptr = (wchar_t *)buffer;
        if (-1 == PyUnicode_AsWideChar((PyUnicodeObject *)value,
                                       buffer, PyUnicode_GET_SIZE(value))) {
            Py_DECREF(value);
            Py_DECREF(keep);
            return NULL;
        }
        Py_DECREF(value);
        return keep;
    }
#endif
}
Exemplo n.º 20
0
/** Convert a PyObject to a TValue as used when calling functions and setting properties in a generic way through Delphi RTTI.
 *  \param O: PyObject to convert
 *  \param TypeInfo: The expected return type
 *  \return A TValue with a value of the type given by TypeInfo.
 *  \throw EPyVclError on conversion errors.
 */
TValue ToValue(PyObject *O, TTypeInfo *TypeInfo)
{
	TValue Result;
	switch(TypeInfo->Kind)
	{
		case tkClass:
			if(VclObject_Check(O))
				Result = TValue::From(VclObject_AsObject(O));
			else if(O == Py_None || PyLong_Check(O))
				Result = TValue::From((TObject*)(O == Py_None ? NULL : PyLong_AsLong(O)));
			else
				throw EPyVclError("Cannot convert Python object of type '" + String(O->ob_type->tp_name) + "' to '" + AnsiString(TypeInfo->Name) + "'");
			break;

		case tkEnumeration:
			if(PyUnicode_Check(O))
				TValue::Make(GetEnumValue(TypeInfo, PyUnicode_AsUnicode(O)), TypeInfo, Result);
			if(PyLong_Check(O))
				TValue::Make(PyLong_AsLong(O), TypeInfo, Result);
			break;

		case tkSet:
			TValue::Make(StringToSet(TypeInfo, PyUnicode_AsUnicode(O)), TypeInfo, Result);
			break;

		case tkInteger:
			Result = TValue::From(PyLong_AsUnsignedLongMask(O));
			break;

		case tkUString:
		case tkString:
		case tkLString:
		case tkWString:
			Result = TValue::From(String(PyUnicode_AsUnicode(O)));
			break;

		case tkChar:
		case tkWChar:
			if(PyUnicode_GetSize(O) != 1)
				throw EPyVclError("Expected string with one character");
			Result = TValue::From(PyUnicode_AsUnicode(O)[0]);
			break;

		case tkFloat:
			Result = TValue::From(PyFloat_AsDouble(O));
			break;

		case tkRecord:
		{
			TRttiType *Type = Context.GetType(TypeInfo);
			std::vector<BYTE> Data(Type->TypeSize);
			DynamicArray<TRttiField*> Fields = Type->GetFields();
			if(PyTuple_Size(O) != Fields.Length)
			  throw EPyVclError("Expected tuple with " + IntToStr(Fields.Length) + " elements");
			for(int I = 0; I < Fields.Length; I++)
				Fields[I]->SetValue(&Data[0], ToValue(PyTuple_GetItem(O, I), Fields[I]->FieldType->Handle));
			TValue::Make(&Data[0], TypeInfo, Result);
			break;
		}

		case tkInt64:
			Result = TValue::From(PyLong_AsLongLong(O));
			break;

		case tkPointer:
      if(AnsiString(TypeInfo->Name) == "PWideChar")
    		TValue::Make(reinterpret_cast<int>(PyUnicode_AsUnicode(O)), TypeInfo, Result);
      else
    		throw EPyVclError("Cannot convert Python object of type '" + String(O->ob_type->tp_name) + "' to '" + AnsiString(TypeInfo->Name) + "'");
      break;

		case tkVariant:
		case tkArray:
		case tkInterface:
		case tkDynArray:
		case tkClassRef:
		case tkProcedure:
		case tkUnknown:
		case tkMethod:
		default:
			throw EPyVclError("Cannot convert Python object of type '" + String(O->ob_type->tp_name) + "' to '" + AnsiString(TypeInfo->Name) + "'");
	}
	if(PyErr_Occurred())
		throw EPyVclError("Cannot convert Python object of type '" + String(O->ob_type->tp_name) + "' to '" + AnsiString(TypeInfo->Name) + "'");
	return Result;
}
Exemplo n.º 21
0
static char *
convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf,
	      size_t bufsize, PyObject **freelist)
{
	char *format = *p_format;
	char c = *format++;
	
	switch (c) {
	
	case 'b': { /* unsigned byte -- very short int */
		char *p = va_arg(*p_va, char *);
		long ival;
		if (float_argument_error(arg))
			return NULL;
		ival = PyInt_AsLong(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<b>", arg, msgbuf, bufsize);
		else if (ival < 0) {
			PyErr_SetString(PyExc_OverflowError,
			"unsigned byte integer is less than minimum");
			return converterr("integer<b>", arg, msgbuf, bufsize);
		}
		else if (ival > UCHAR_MAX) {
			PyErr_SetString(PyExc_OverflowError,
			"unsigned byte integer is greater than maximum");
			return converterr("integer<b>", arg, msgbuf, bufsize);
		}
		else
			*p = (unsigned char) ival;
		break;
	}
	
	case 'B': {/* byte sized bitfield - both signed and unsigned
		      values allowed */  
		char *p = va_arg(*p_va, char *);
		long ival;
		if (float_argument_error(arg))
			return NULL;
		ival = PyInt_AsUnsignedLongMask(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<B>", arg, msgbuf, bufsize);
		else
			*p = (unsigned char) ival;
		break;
	}
	
	case 'h': {/* signed short int */
		short *p = va_arg(*p_va, short *);
		long ival;
		if (float_argument_error(arg))
			return NULL;
		ival = PyInt_AsLong(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<h>", arg, msgbuf, bufsize);
		else if (ival < SHRT_MIN) {
			PyErr_SetString(PyExc_OverflowError,
			"signed short integer is less than minimum");
			return converterr("integer<h>", arg, msgbuf, bufsize);
		}
		else if (ival > SHRT_MAX) {
			PyErr_SetString(PyExc_OverflowError,
			"signed short integer is greater than maximum");
			return converterr("integer<h>", arg, msgbuf, bufsize);
		}
		else
			*p = (short) ival;
		break;
	}
	
	case 'H': { /* short int sized bitfield, both signed and
		       unsigned allowed */ 
		unsigned short *p = va_arg(*p_va, unsigned short *);
		long ival;
		if (float_argument_error(arg))
			return NULL;
		ival = PyInt_AsUnsignedLongMask(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<H>", arg, msgbuf, bufsize);
		else
			*p = (unsigned short) ival;
		break;
	}
	
	case 'i': {/* signed int */
		int *p = va_arg(*p_va, int *);
		long ival;
		if (float_argument_error(arg))
			return NULL;
		ival = PyInt_AsLong(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<i>", arg, msgbuf, bufsize);
		else if (ival > INT_MAX) {
			PyErr_SetString(PyExc_OverflowError,
				"signed integer is greater than maximum");
			return converterr("integer<i>", arg, msgbuf, bufsize);
		}
		else if (ival < INT_MIN) {
			PyErr_SetString(PyExc_OverflowError,
				"signed integer is less than minimum");
			return converterr("integer<i>", arg, msgbuf, bufsize);
		}
		else
			*p = ival;
		break;
	}

	case 'I': { /* int sized bitfield, both signed and
		       unsigned allowed */ 
		unsigned int *p = va_arg(*p_va, unsigned int *);
		unsigned int ival;
		if (float_argument_error(arg))
			return NULL;
		ival = PyInt_AsUnsignedLongMask(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<I>", arg, msgbuf, bufsize);
		else
			*p = ival;
		break;
	}
	
	case 'l': {/* long int */
		long *p = va_arg(*p_va, long *);
		long ival;
		if (float_argument_error(arg))
			return NULL;
		ival = PyInt_AsLong(arg);
		if (ival == -1 && PyErr_Occurred())
			return converterr("integer<l>", arg, msgbuf, bufsize);
		else
			*p = ival;
		break;
	}

	case 'k': { /* long sized bitfield */
		unsigned long *p = va_arg(*p_va, unsigned long *);
		unsigned long ival;
		if (PyInt_Check(arg))
			ival = PyInt_AsUnsignedLongMask(arg);
		else if (PyLong_Check(arg))
			ival = PyLong_AsUnsignedLongMask(arg);
		else
			return converterr("integer<k>", arg, msgbuf, bufsize);
		*p = ival;
		break;
	}
	
	case 'f': {/* float */
		float *p = va_arg(*p_va, float *);
		double dval = PyFloat_AsDouble(arg);
		if (PyErr_Occurred())
			return converterr("float<f>", arg, msgbuf, bufsize);
		else
			*p = (float) dval;
		break;
	}
	
	case 'd': {/* double */
		double *p = va_arg(*p_va, double *);
		double dval = PyFloat_AsDouble(arg);
		if (PyErr_Occurred())
			return converterr("float<d>", arg, msgbuf, bufsize);
		else
			*p = dval;
		break;
	}
	
	case 'c': {/* char */
		char *p = va_arg(*p_va, char *);
		if (PyString_Check(arg) && PyString_Size(arg) == 1)
			*p = PyString_AS_STRING(arg)[0];
		else
			return converterr("char", arg, msgbuf, bufsize);
		break;
	}
	
	case 's': {/* string */
		if (*format == '#') {
			void **p = (void **)va_arg(*p_va, char **);
			int *q = va_arg(*p_va, int *);
			
			if (PyString_Check(arg)) {
				*p = PyString_AS_STRING(arg);
				*q = PyString_GET_SIZE(arg);
			}
			else { /* any buffer-like object */
				char *buf;
				int count = convertbuffer(arg, p, &buf);
				if (count < 0)
					return converterr(buf, arg, msgbuf, bufsize);
				*q = count;
			}
			format++;
		} else {
			char **p = va_arg(*p_va, char **);
			
			if (PyString_Check(arg))
				*p = PyString_AS_STRING(arg);
			else
				return converterr("string", arg, msgbuf, bufsize);
			if ((int)strlen(*p) != PyString_Size(arg))
				return converterr("string without null bytes",
						  arg, msgbuf, bufsize);
		}
		break;
	}
Exemplo n.º 22
0
int
SharedMemory_init(SharedMemory *self, PyObject *args, PyObject *keywords) {
    NoneableKey key;
    int mode = 0600;
    unsigned long size = 0;
    int shmget_flags = 0;
    int shmat_flags = 0;
    char init_character = ' ';
    char *keyword_list[ ] = {"key", "flags", "mode", "size", "init_character", NULL};
    PyObject *py_size = NULL;

    DPRINTF("Inside SharedMemory_init()\n");

    if (!PyArg_ParseTupleAndKeywords(args, keywords, "O&|iikc", keyword_list,
                                     &convert_key_param, &key,
                                     &shmget_flags, &mode, &size,
                                     &init_character))
        goto error_return;

    mode &= 0777;
    shmget_flags &= ~0777;

    DPRINTF("key is none = %d, key value = %ld\n", key.is_none, (long)key.value);

    if ( !(shmget_flags & IPC_CREAT) && (shmget_flags & IPC_EXCL) ) {
        PyErr_SetString(PyExc_ValueError,
                "IPC_EXCL must be combined with IPC_CREAT");
        goto error_return;
    }

    if (key.is_none && ((shmget_flags & IPC_EXCL) != IPC_EXCL)) {
        PyErr_SetString(PyExc_ValueError,
                "Key can only be None if IPC_EXCL is set");
        goto error_return;
    }

    // When creating a new segment, the default size is PAGE_SIZE.
    if (((shmget_flags & IPC_CREX) == IPC_CREX) && (!size))
        size = PAGE_SIZE;

    if (key.is_none) {
        // (key == None) ==> generate a key for the caller
        do {
            errno = 0;
            self->key = get_random_key();

            DPRINTF("Calling shmget, key=%ld, size=%lu, mode=%o, flags=0x%x\n",
                    (long)self->key, size, mode, shmget_flags);
            self->id = shmget(self->key, size, mode | shmget_flags);
        } while ( (-1 == self->id) && (EEXIST == errno) );
    }
    else {
        // (key != None) ==> use key supplied by the caller
        self->key = key.value;

        DPRINTF("Calling shmget, key=%ld, size=%lu, mode=%o, flags=0x%x\n",
                (long)self->key, size, mode, shmget_flags);
        self->id = shmget(self->key, size, mode | shmget_flags);
    }

    DPRINTF("id == %d\n", self->id);

    if (self->id == -1) {
        switch (errno) {
            case EACCES:
                PyErr_Format(pPermissionsException,
                             "Permission %o cannot be granted on the existing segment",
                             mode);
            break;

            case EEXIST:
                PyErr_Format(pExistentialException,
                    "Shared memory with the key %ld already exists",
                    (long)self->key);
            break;

            case ENOENT:
                PyErr_Format(pExistentialException,
                    "No shared memory exists with the key %ld", (long)self->key);
            break;

            case EINVAL:
                PyErr_SetString(PyExc_ValueError, "The size is invalid");
            break;

            case ENOMEM:
                PyErr_SetString(PyExc_MemoryError, "Not enough memory");
            break;

            case ENOSPC:
                PyErr_SetString(PyExc_OSError,
                    "Not enough shared memory identifiers available (ENOSPC)");
            break;

            default:
                PyErr_SetFromErrno(PyExc_OSError);
            break;
        }
        goto error_return;
    }

    // Attach the memory. If no write permissions requested, attach read-only.
    shmat_flags = (mode & 0200) ? 0 : SHM_RDONLY;
    if (NULL == shm_attach(self, NULL, shmat_flags)) {
        // Bad news, something went wrong.
        goto error_return;
    }

    if ( ((shmget_flags & IPC_CREX) == IPC_CREX) && (!(shmat_flags & SHM_RDONLY)) ) {
        // Initialize the memory.

        py_size = shm_get_value(self->id, SVIFP_SHM_SIZE);

        if (!py_size)
            goto error_return;
        else {
#if PY_MAJOR_VERSION > 2
            size = PyLong_AsUnsignedLongMask(py_size);
#else
            size = PyInt_AsUnsignedLongMask(py_size);
#endif

            DPRINTF("memsetting address %p to %lu bytes of ASCII 0x%x (%c)\n", \
                    self->address, size, (int)init_character, init_character);
            memset(self->address, init_character, size);
        }

        Py_DECREF(py_size);
    }

    return 0;

    error_return:
    return -1;
}