// The type init slot.
static int pyqtSignal_init(PyObject *self, PyObject *args, PyObject *kwd_args)
{
    qpycore_pyqtSignal *ps = (qpycore_pyqtSignal *)self;

    // We are the signal master.
    ps->master = ps;
    ps->overloads = new QList<Chimera::Signature *>;

    // Get the keyword arguments.
    PyObject *name_obj = 0;
    const char *name = 0;

    if (kwd_args)
    {
        SIP_SSIZE_T pos = 0;
        PyObject *key, *value;

        while (PyDict_Next(kwd_args, &pos, &key, &value))
        {
#if PY_MAJOR_VERSION >= 3
            if (PyUnicode_CompareWithASCIIString(key, "name") != 0)
            {
                PyErr_Format(PyExc_TypeError,
                        "pyqtSignal() got an unexpected keyword argument '%U'",
                        key);

                Py_XDECREF(name_obj);
                return -1;
            }
#else
            Q_ASSERT(PyString_Check(key));

            if (qstrcmp(PyString_AS_STRING(key), "name") != 0)
            {
                PyErr_Format(PyExc_TypeError,
                        "pyqtSignal() got an unexpected keyword argument '%s'",
                        PyString_AS_STRING(key));

                Py_XDECREF(name_obj);
                return -1;
            }
#endif

            name_obj = value;
            name = sipString_AsASCIIString(&name_obj);

            if (!name)
                return -1;
        }
    }

    // If there is at least one argument and it is a sequence then assume all
    // arguments are sequences.  Unfortunately a string is also a sequence so
    // check for tuples and lists explicitly.
    if (PyTuple_GET_SIZE(args) > 0 && (PyTuple_Check(PyTuple_GET_ITEM(args, 0)) || PyList_Check(PyTuple_GET_ITEM(args, 0))))
    {
        for (SIP_SSIZE_T i = 0; i < PyTuple_GET_SIZE(args); ++i)
        {
            PyObject *types = PySequence_Tuple(PyTuple_GET_ITEM(args, i));

            if (!types)
            {
                PyErr_SetString(PyExc_TypeError,
                        "pyqtSignal() argument expected to be sequence of types");

                if (name)
                {
                    Py_DECREF(name_obj);
                }

                return -1;
            }

            int rc = add_overload(ps, name, types);

            Py_DECREF(types);

            if (rc < 0)
            {
                if (name)
                {
                    Py_DECREF(name_obj);
                }

                return -1;
            }
        }
    }
    else if (add_overload(ps, name, args) < 0)
    {
        if (name)
        {
            Py_DECREF(name_obj);
        }

        return -1;
    }

    if (name)
    {
        Py_DECREF(name_obj);
    }

    return 0;
}
示例#2
0
struct t_hashtable *
weechat_python_dict_to_hashtable (PyObject *dict, int size,
                                  const char *type_keys,
                                  const char *type_values)
{
    struct t_hashtable *hashtable;
    PyObject *key, *value;
    Py_ssize_t pos;
    char *str_key, *str_value;

    hashtable = weechat_hashtable_new (size, type_keys, type_values,
                                       NULL, NULL);
    if (!hashtable)
        return NULL;

    pos = 0;
    while (PyDict_Next (dict, &pos, &key, &value))
    {
        str_key = NULL;
        str_value = NULL;
        if (PyBytes_Check (key))
        {
            if (PyBytes_AsString (key))
                str_key = strdup (PyBytes_AsString (key));
        }
        else
        {
            str_key = weechat_python_unicode_to_string (key);
        }
        if (PyBytes_Check (value))
        {
            if (PyBytes_AsString (value))
                str_value = strdup (PyBytes_AsString (value));
        }
        else
        {
            str_value = weechat_python_unicode_to_string (value);
        }

        if (str_key)
        {
            if (strcmp (type_values, WEECHAT_HASHTABLE_STRING) == 0)
            {
                weechat_hashtable_set (hashtable, str_key, str_value);
            }
            else if (strcmp (type_values, WEECHAT_HASHTABLE_POINTER) == 0)
            {
                weechat_hashtable_set (hashtable, str_key,
                                       plugin_script_str2ptr (weechat_python_plugin,
                                                              NULL, NULL,
                                                              str_value));
            }
        }

        if (str_key)
            free (str_key);
        if (str_value)
            free (str_value);
    }

    return hashtable;
}
示例#3
0
static void
pyobj2doc(PyObject *object, rapidjson::Document& doc)
{
    if (PyBool_Check(object)) {
        if (Py_True == object) {
	        doc.SetBool(true);
        }
        else {
	        doc.SetBool(false);
        }
    }
    else if (Py_None == object) {
        doc.SetNull();
    }
    else if (PyFloat_Check(object)) {
        doc.SetDouble(PyFloat_AsDouble(object));
    }
    else if (PyInt_Check(object)) {
        doc.SetInt(PyLong_AsLong(object));
    }
    else if (PyString_Check(object)) {
        doc.SetString(PyString_AsString(object), PyString_GET_SIZE(object));
    }
    else if (PyUnicode_Check(object)) {
#ifdef PY3
        PyObject *utf8_item;
        utf8_item = PyUnicode_AsUTF8String(object);
        if (!utf8_item) {
            // TODO: error handling
            printf("error\n");
        }

        doc.SetString(PyBytes_AsString(utf8_item),
                      PyBytes_Size(utf8_item), doc.GetAllocator());

        Py_XDECREF(utf8_item);
#else
        doc.SetString(PyBytes_AsString(object), PyBytes_GET_SIZE(object));
#endif
    }
    else if (PyTuple_Check(object)) {
        int len = PyTuple_Size(object), i;
        doc.SetArray();
        rapidjson::Value _v;
        for (i = 0; i < len; ++i) {
            PyObject *elm = PyList_GetItem(object, i);
            pyobj2doc(elm, _v, doc);
            doc.PushBack(_v, doc.GetAllocator());
        }
    }
    else if (PyList_Check(object)) {
        int len = PyList_Size(object), i;
        doc.SetArray();
        rapidjson::Value _v;
        for (i = 0; i < len; ++i) {
            PyObject *elm = PyList_GetItem(object, i);
            pyobj2doc(elm, _v, doc);
            doc.PushBack(_v, doc.GetAllocator());
        }
    }
    else if (PyDict_Check(object)) {
        doc.SetObject();
        PyObject *key, *value;
        Py_ssize_t pos = 0;
        while (PyDict_Next(object, &pos, &key, &value)) {
            pyobj2doc_pair(key, value, doc);
        }
    }
    else {
        // TODO: error handle
    }
}
示例#4
0
PyObject* ItemSupplier::create(PyTypeObject* pytype, PyObject* args, PyObject* kwds)
{
  try
  {
    // Pick up the supplier
    PyObject* sup = PyDict_GetItemString(kwds,"supplier");
    if (!sup)
      throw DataException("missing supplier on ItemSupplier");
    if (!PyObject_TypeCheck(sup, Supplier::metadata->pythonClass))
      throw DataException("ItemSupplier supplier must be of type supplier");

    // Pick up the item
    PyObject* it = PyDict_GetItemString(kwds,"item");
    if (!it)
      throw DataException("missing item on ItemSupplier");
    if (!PyObject_TypeCheck(it, Item::metadata->pythonClass))
      throw DataException("ItemSupplier item must be of type item");

    // Pick up the priority
    PyObject* q1 = PyDict_GetItemString(kwds,"priority");
    int q2 = q1 ? PythonData(q1).getInt() : 1;

    // Pick up the effective dates
    DateRange eff;
    PyObject* eff_start = PyDict_GetItemString(kwds,"effective_start");
    if (eff_start)
    {
      PythonData d(eff_start);
      eff.setStart(d.getDate());
    }
    PyObject* eff_end = PyDict_GetItemString(kwds,"effective_end");
    if (eff_end)
    {
      PythonData d(eff_end);
      eff.setEnd(d.getDate());
    }

    // Create the ItemSupplier
    ItemSupplier *l = new ItemSupplier(
      static_cast<Supplier*>(sup),
      static_cast<Item*>(it),
      q2, eff
    );

    // Iterate over extra keywords, and set attributes.   @todo move this responsibility to the readers...
    if (l)
    {
      PyObject *key, *value;
      Py_ssize_t pos = 0;
      while (PyDict_Next(kwds, &pos, &key, &value))
      {
        PythonData field(value);
        PyObject* key_utf8 = PyUnicode_AsUTF8String(key);
        DataKeyword attr(PyBytes_AsString(key_utf8));
        Py_DECREF(key_utf8);
        if (!attr.isA(Tags::effective_end) && !attr.isA(Tags::effective_start)
          && !attr.isA(Tags::supplier) && !attr.isA(Tags::item)
          && !attr.isA(Tags::type) && !attr.isA(Tags::action))
        {
          const MetaFieldBase* fmeta = l->getType().findField(attr.getHash());
          if (!fmeta && l->getType().category)
            fmeta = l->getType().category->findField(attr.getHash());
          if (fmeta)
            // Update the attribute
            fmeta->setField(l, field);
          else
            l->setProperty(attr.getName(), value);
        }
      };
    }

    // Return the object
    Py_INCREF(l);
    return static_cast<PyObject*>(l);
  }
  catch (...)
  {
    PythonType::evalException();
    return NULL;
  }
}
static void _build_translations_cache(PyObject *py_messages, const char *locale)
{
	PyObject *uuid, *uuid_dict;
	Py_ssize_t pos = 0;
	char *language = NULL, *language_country = NULL, *language_variant = NULL;

	/* For each py dict, we'll search for full locale, then language+country, then language+variant,
	 * then only language keys... */
	BLF_locale_explode(locale, &language, NULL, NULL, &language_country, &language_variant);

	/* Clear the cached ghash if needed, and create a new one. */
	_clear_translations_cache();
	_translations_cache = BLI_ghash_new(_ghashutil_keyhash, _ghashutil_keycmp, __func__);

	/* Iterate over all py dicts. */
	while (PyDict_Next(py_messages, &pos, &uuid, &uuid_dict)) {
		PyObject *lang_dict;

#if 0
		PyObject_Print(uuid_dict, stdout, 0);
		printf("\n");
#endif

		/* Try to get first complete locale, then language+country, then language+variant, then only language */
		lang_dict = PyDict_GetItemString(uuid_dict, locale);
		if (!lang_dict && language_country) {
			lang_dict = PyDict_GetItemString(uuid_dict, language_country);
			locale = language_country;
		}
		if (!lang_dict && language_variant) {
			lang_dict = PyDict_GetItemString(uuid_dict, language_variant);
			locale = language_variant;
		}
		if (!lang_dict && language) {
			lang_dict = PyDict_GetItemString(uuid_dict, language);
			locale = language;
		}

		if (lang_dict) {
			PyObject *pykey, *trans;
			Py_ssize_t ppos = 0;

			if (!PyDict_Check(lang_dict)) {
				printf("WARNING! In translations' dict of \"");
				PyObject_Print(uuid, stdout, Py_PRINT_RAW);
				printf("\":\n");
				printf("    Each language key must have a dictionary as value, \"%s\" is not valid, skipping: ",
				       locale);
				PyObject_Print(lang_dict, stdout, Py_PRINT_RAW);
				printf("\n");
				continue;
			}

			/* Iterate over all translations of the found language dict, and populate our ghash cache. */
			while (PyDict_Next(lang_dict, &ppos, &pykey, &trans)) {
				GHashKey *key;
				const char *msgctxt = NULL, *msgid = NULL;
				bool invalid_key = false;

				if ((PyTuple_CheckExact(pykey) == false) || (PyTuple_GET_SIZE(pykey) != 2)) {
					invalid_key = true;
				}
				else {
					PyObject *tmp = PyTuple_GET_ITEM(pykey, 0);
					if (tmp == Py_None) {
						msgctxt = BLF_I18NCONTEXT_DEFAULT_BPYRNA;
					}
					else if (PyUnicode_Check(tmp)) {
						msgctxt = _PyUnicode_AsString(tmp);
					}
					else {
						invalid_key = true;
					}

					tmp = PyTuple_GET_ITEM(pykey, 1);
					if (PyUnicode_Check(tmp)) {
						msgid = _PyUnicode_AsString(tmp);
					}
					else {
						invalid_key = true;
					}
				}

				if (invalid_key) {
					printf("WARNING! In translations' dict of \"");
					PyObject_Print(uuid, stdout, Py_PRINT_RAW);
					printf("\", %s language:\n", locale);
					printf("    Keys must be tuples of (msgctxt [string or None], msgid [string]), "
					       "this one is not valid, skipping: ");
					PyObject_Print(pykey, stdout, Py_PRINT_RAW);
					printf("\n");
					continue;
				}
				if (PyUnicode_Check(trans) == false) {
					printf("WARNING! In translations' dict of \"");
					PyObject_Print(uuid, stdout, Py_PRINT_RAW);
					printf("\":\n");
					printf("    Values must be strings, this one is not valid, skipping: ");
					PyObject_Print(trans, stdout, Py_PRINT_RAW);
					printf("\n");
					continue;
				}

				key = _ghashutil_keyalloc(msgctxt, msgid);

				/* Do not overwrite existing keys! */
				if (BLI_ghash_lookup(_translations_cache, (void *)key)) {
					continue;
				}

				BLI_ghash_insert(_translations_cache, key, BLI_strdup(_PyUnicode_AsString(trans)));
			}
		}
	}

	/* Clean up! */
	if (language)
		MEM_freeN(language);
	if (language_country)
		MEM_freeN(language_country);
	if (language_variant)
		MEM_freeN(language_variant);
}
示例#6
0
static PyObject *
pickle_copy_dict(PyObject *state)
{
    PyObject *copy, *key, *value;
    char *ckey;
    Py_ssize_t pos = 0;

    copy = PyDict_New();
    if (!copy)
        return NULL;

    if (!state)
        return copy;

    while (PyDict_Next(state, &pos, &key, &value))
    {
        int is_special;
#ifdef PY3K
        if (key && PyUnicode_Check(key))
        {
            PyObject *converted = convert_name(key);
            ckey = PyBytes_AS_STRING(converted);
#else
        if (key && PyBytes_Check(key))
        {
            ckey = PyBytes_AS_STRING(key);
#endif
            is_special = (*ckey == '_' &&
                          (ckey[1] == 'v' || ckey[1] == 'p') &&
                          ckey[2] == '_');
#ifdef PY3K
            Py_DECREF(converted);
#endif
            if (is_special) /* skip volatile and persistent */
                continue;
        }

        if (PyObject_SetItem(copy, key, value) < 0)
            goto err;
    }

    return copy;
err:
    Py_DECREF(copy);
    return NULL;
}


static char pickle___getstate__doc[] =
    "Get the object serialization state\n"
    "\n"
    "If the object has no assigned slots and has no instance dictionary, then \n"
    "None is returned.\n"
    "\n"
    "If the object has no assigned slots and has an instance dictionary, then \n"
    "the a copy of the instance dictionary is returned. The copy has any items \n"
    "with names starting with '_v_' or '_p_' ommitted.\n"
    "\n"
    "If the object has assigned slots, then a two-element tuple is returned.  \n"
    "The first element is either None or a copy of the instance dictionary, \n"
    "as described above. The second element is a dictionary with items \n"
    "for each of the assigned slots.\n"
    ;

static PyObject *
pickle___getstate__(PyObject *self)
{
    PyObject *slotnames=NULL, *slots=NULL, *state=NULL;
    PyObject **dictp;
    int n=0;

    slotnames = pickle_slotnames(Py_TYPE(self));
    if (!slotnames)
        return NULL;

    dictp = _PyObject_GetDictPtr(self);
    if (dictp)
        state = pickle_copy_dict(*dictp);
    else
    {
        state = Py_None;
        Py_INCREF(state);
    }

    if (slotnames != Py_None)
    {
        int i;

        slots = PyDict_New();
        if (!slots)
            goto end;

        for (i = 0; i < PyList_GET_SIZE(slotnames); i++)
        {
            PyObject *name, *value;
            char *cname;
            int is_special;

            name = PyList_GET_ITEM(slotnames, i);
#ifdef PY3K
            if (PyUnicode_Check(name))
            {
                PyObject *converted = convert_name(name);
                cname = PyBytes_AS_STRING(converted);
#else
            if (PyBytes_Check(name))
            {
                cname = PyBytes_AS_STRING(name);
#endif
                is_special = (*cname == '_' &&
                              (cname[1] == 'v' || cname[1] == 'p') &&
                              cname[2] == '_');
#ifdef PY3K
                Py_DECREF(converted);
#endif
                if (is_special) /* skip volatile and persistent */
                {
                    continue;
                }
            }

            /* Unclear:  Will this go through our getattr hook? */
            value = PyObject_GetAttr(self, name);
            if (value == NULL)
                PyErr_Clear();
            else
            {
                int err = PyDict_SetItem(slots, name, value);
                Py_DECREF(value);
                if (err < 0)
                    goto end;
                n++;
            }
        }
    }

    if (n)
        state = Py_BuildValue("(NO)", state, slots);

end:
    Py_XDECREF(slotnames);
    Py_XDECREF(slots);

    return state;
}

static int
pickle_setattrs_from_dict(PyObject *self, PyObject *dict)
{
    PyObject *key, *value;
    Py_ssize_t pos = 0;

    if (!PyDict_Check(dict))
    {
        PyErr_SetString(PyExc_TypeError, "Expected dictionary");
        return -1;
    }

    while (PyDict_Next(dict, &pos, &key, &value))
    {
        if (PyObject_SetAttr(self, key, value) < 0)
            return -1;
    }
    return 0;
}
/* add a lastError message on the end of the buffer.
 * returns 0 on failure */
static int add_last_error(PyObject* self, buffer_t buffer,
                          int request_id, char* ns, int nslen,
                          codec_options_t* options, PyObject* args) {
    struct module_state *state = GETSTATE(self);

    int message_start;
    int document_start;
    int message_length;
    int document_length;
    PyObject* key;
    PyObject* value;
    Py_ssize_t pos = 0;
    PyObject* one;
    char *p = strchr(ns, '.');
    /* Length of the database portion of ns. */
    nslen = p ? (int)(p - ns) : nslen;

    message_start = buffer_save_space(buffer, 4);
    if (message_start == -1) {
        PyErr_NoMemory();
        return 0;
    }
    if (!buffer_write_bytes(buffer, (const char*)&request_id, 4) ||
        !buffer_write_bytes(buffer,
                            "\x00\x00\x00\x00"  /* responseTo */
                            "\xd4\x07\x00\x00"  /* opcode */
                            "\x00\x00\x00\x00", /* options */
                            12) ||
        !buffer_write_bytes(buffer,
                            ns, nslen) ||       /* database */
        !buffer_write_bytes(buffer,
                            ".$cmd\x00"         /* collection name */
                            "\x00\x00\x00\x00"  /* skip */
                            "\xFF\xFF\xFF\xFF", /* limit (-1) */
                            14)) {
        return 0;
    }

    /* save space for length */
    document_start = buffer_save_space(buffer, 4);
    if (document_start == -1) {
        PyErr_NoMemory();
        return 0;
    }

    /* getlasterror: 1 */
    if (!(one = PyLong_FromLong(1)))
        return 0;

    if (!write_pair(state->_cbson, buffer, "getlasterror", 12, one, 0,
                    options, 1)) {
        Py_DECREF(one);
        return 0;
    }
    Py_DECREF(one);

    /* getlasterror options */
    while (PyDict_Next(args, &pos, &key, &value)) {
        if (!decode_and_write_pair(state->_cbson, buffer, key, value, 0,
                                   options, 0)) {
            return 0;
        }
    }

    /* EOD */
    if (!buffer_write_bytes(buffer, "\x00", 1)) {
        return 0;
    }

    message_length = buffer_get_position(buffer) - message_start;
    document_length = buffer_get_position(buffer) - document_start;
    memcpy(buffer_get_buffer(buffer) + message_start, &message_length, 4);
    memcpy(buffer_get_buffer(buffer) + document_start, &document_length, 4);
    return 1;
}
示例#8
0
static ucl_object_t *
_iterate_python (PyObject *obj)
{
	if (obj == Py_None) {
		return ucl_object_new();
	}
	else if (PyBool_Check (obj)) {
		return ucl_object_frombool (obj == Py_True);
	}
#if PY_MAJOR_VERSION < 3
	else if (PyInt_Check (obj)) {
		return ucl_object_fromint (PyInt_AsLong (obj));
	}
#endif
	else if (PyLong_Check (obj)) {
		return ucl_object_fromint (PyLong_AsLong (obj));
	}
	else if (PyFloat_Check (obj)) {
		return ucl_object_fromdouble (PyFloat_AsDouble (obj));
	}
	else if (PyUnicode_Check (obj)) {
		ucl_object_t *ucl_str;
		PyObject *str = PyUnicode_AsASCIIString(obj);
		ucl_str = ucl_object_fromstring (PyBytes_AsString (str));
		Py_DECREF(str);
		return ucl_str;
	}
#if PY_MAJOR_VERSION < 3
	else if (PyString_Check (obj)) {
		return ucl_object_fromstring (PyString_AsString (obj));
	}
#endif
	else if (PyDict_Check(obj)) {
		PyObject *key, *value;
		Py_ssize_t pos = 0;
		ucl_object_t *top, *elm;
		char *keystr = NULL;

		top = ucl_object_typed_new (UCL_OBJECT);

		while (PyDict_Next(obj, &pos, &key, &value)) {
			elm = _iterate_python(value);
			
			if (PyUnicode_Check(key)) {
				PyObject *keyascii = PyUnicode_AsASCIIString(key);
				keystr = PyBytes_AsString(keyascii);
				Py_DECREF(keyascii);
			}
#if PY_MAJOR_VERSION < 3
			else if (PyString_Check(key)) {
				keystr = PyString_AsString(key);
			}
#endif
			else {
				PyErr_SetString(PyExc_TypeError, "Unknown key type");
				return NULL;
			}

			ucl_object_insert_key (top, elm, keystr, 0, true);
		}

		return top;
	}
	else if (PySequence_Check(obj)) {
		PyObject *value;
		Py_ssize_t len, pos;
		ucl_object_t *top, *elm;

		len  = PySequence_Length(obj);
		top = ucl_object_typed_new (UCL_ARRAY);

		for (pos = 0; pos < len; pos++) {
			value = PySequence_GetItem(obj, pos);
			elm = _iterate_python(value);
			ucl_array_append(top, elm);
		}

		return top;
	}
	else {
		PyErr_SetString(PyExc_TypeError, "Unhandled object type");
		return NULL;
	}

	return NULL;
}
示例#9
0
static uint32_t pointless_export_py_rec(pointless_export_state_t* state, PyObject* py_object, uint32_t depth)
{
	// don't go too deep
	if (depth >= POINTLESS_MAX_DEPTH) {
		PyErr_SetString(PyExc_ValueError, "structure is too deep");
		state->is_error = 1;
		printf("line: %i\n", __LINE__);
		state->error_line = __LINE__;
		return POINTLESS_CREATE_VALUE_FAIL;
	}

	// check simple types first
	uint32_t handle = POINTLESS_CREATE_VALUE_FAIL;

	// return an error on failure
	#define RETURN_OOM(state) {PyErr_NoMemory(); (state)->is_error = 1; printf("line: %i\n", __LINE__); state->error_line = __LINE__; return POINTLESS_CREATE_VALUE_FAIL;}
	#define RETURN_OOM_IF_FAIL(handle, state) if ((handle) == POINTLESS_CREATE_VALUE_FAIL) RETURN_OOM(state);

	// booleans, need this above integer check, cause PyInt_Check return 1 for booleans
	if (PyBool_Check(py_object)) {
		if (py_object == Py_True)
			handle = pointless_create_boolean_true(&state->c);
		else
			handle = pointless_create_boolean_false(&state->c);

		RETURN_OOM_IF_FAIL(handle, state);
	// integer
	} else if (PyInt_Check(py_object)) {
		long v = PyInt_AS_LONG(py_object);

		// unsigned
		if (v >= 0) {
			if (v > UINT32_MAX) {
				PyErr_Format(PyExc_ValueError, "integer too large for mere 32 bits");
				printf("line: %i\n", __LINE__);
				state->is_error = 1;
				state->error_line = __LINE__;
				return POINTLESS_CREATE_VALUE_FAIL;
			}

			handle = pointless_create_u32(&state->c, (uint32_t)v);
		// signed
		} else {
			if (!(INT32_MIN <= v && v <= INT32_MAX)) {
				PyErr_Format(PyExc_ValueError, "integer too large for mere 32 bits with a sign");
				printf("line: %i\n", __LINE__);
				state->is_error = 1;
				state->error_line = __LINE__;
				return POINTLESS_CREATE_VALUE_FAIL;
			}

			handle = pointless_create_i32(&state->c, (int32_t)v);
		}

		RETURN_OOM_IF_FAIL(handle, state);
	// long
	} else if (PyLong_Check(py_object)) {
		// this will raise an overflow error if number is outside the legal range of PY_LONG_LONG
		PY_LONG_LONG v = PyLong_AsLongLong(py_object);

		// if there was an exception, clear it, and set our own
		if (PyErr_Occurred()) {
			PyErr_Clear();
			PyErr_SetString(PyExc_ValueError, "value of long is way beyond what we can store right now");
			printf("line: %i\n", __LINE__);
			state->is_error = 1;
			state->error_line = __LINE__;
			return POINTLESS_CREATE_VALUE_FAIL;
		}

		// unsigned
		if (v >= 0) {
			if (v > UINT32_MAX) {
				PyErr_Format(PyExc_ValueError, "long too large for mere 32 bits");
				printf("line: %i\n", __LINE__);
				state->is_error = 1;
				state->error_line = __LINE__;
				return POINTLESS_CREATE_VALUE_FAIL;
			}

			handle = pointless_create_u32(&state->c, (uint32_t)v);
		// signed
		} else {
			if (!(INT32_MIN <= v && v <= INT32_MAX)) {
				PyErr_Format(PyExc_ValueError, "long too large for mere 32 bits with a sign");
				printf("line: %i\n", __LINE__);
				state->is_error = 1;
				state->error_line = __LINE__;
				return POINTLESS_CREATE_VALUE_FAIL;
			}

			handle = pointless_create_i32(&state->c, (int32_t)v);
		}

		RETURN_OOM_IF_FAIL(handle, state);
	// None object
	} else if (py_object == Py_None) {
		handle = pointless_create_null(&state->c);
		RETURN_OOM_IF_FAIL(handle, state);
	} else if (PyFloat_Check(py_object)) {
		handle = pointless_create_float(&state->c, (float)PyFloat_AS_DOUBLE(py_object));
		RETURN_OOM_IF_FAIL(handle, state);
	}

	if (handle != POINTLESS_CREATE_VALUE_FAIL)
		return handle;

	// remaining types are containers/big-values, which we track
	// either for space-savings or maintaining circular references

	// if object has been seen before, return its handle
	handle = pointless_export_get_seen(state, py_object);

	if (handle != POINTLESS_CREATE_VALUE_FAIL)
		return handle;

	// list/tuple object
	if (PyList_Check(py_object) || PyTuple_Check(py_object)) {
		// create and cache handle
		assert(is_container(py_object));

		handle = pointless_create_vector_value(&state->c);
		RETURN_OOM_IF_FAIL(handle, state);

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

		// populate vector
		Py_ssize_t i, n_items = PyList_Check(py_object) ? PyList_GET_SIZE(py_object) : PyTuple_GET_SIZE(py_object);

		for (i = 0; i < n_items; i++) {
			PyObject* child = PyList_Check(py_object) ? PyList_GET_ITEM(py_object, i) : PyTuple_GET_ITEM(py_object, i);
			uint32_t child_handle = pointless_export_py_rec(state, child, depth + 1);

			if (child_handle == POINTLESS_CREATE_VALUE_FAIL)
				return child_handle;

			if (pointless_create_vector_value_append(&state->c, handle, child_handle) == POINTLESS_CREATE_VALUE_FAIL) {
				RETURN_OOM(state);
			}
		}

	// pointless value vectors
	} else if (PyPointlessVector_Check(py_object)) {
		// currently, we only support value vectors, they are simple
		PyPointlessVector* v = (PyPointlessVector*)py_object;
		const char* error = 0;

		switch(v->v->type) {
			case POINTLESS_VECTOR_VALUE:
			case POINTLESS_VECTOR_VALUE_HASHABLE:
				handle = pointless_recreate_value(&v->pp->p, v->v, &state->c, &error);

				if (handle == POINTLESS_CREATE_VALUE_FAIL) {
					printf("line: %i\n", __LINE__);
					state->is_error = 1;
					state->error_line = __LINE__;
					PyErr_Format(PyExc_ValueError, "pointless_recreate_value(): %s", error);
					return POINTLESS_CREATE_VALUE_FAIL;
				}

				break;
			case POINTLESS_VECTOR_I8:
				handle = pointless_create_vector_i8_owner(&state->c, pointless_reader_vector_i8(&v->pp->p, v->v) + v->slice_i, v->slice_n);
				break;
			case POINTLESS_VECTOR_U8:
				handle = pointless_create_vector_u8_owner(&state->c, pointless_reader_vector_u8(&v->pp->p, v->v) + v->slice_i, v->slice_n);
				break;
			case POINTLESS_VECTOR_I16:
				handle = pointless_create_vector_i16_owner(&state->c, pointless_reader_vector_i16(&v->pp->p, v->v) + v->slice_i, v->slice_n);
				break;
			case POINTLESS_VECTOR_U16:
				handle = pointless_create_vector_u16_owner(&state->c, pointless_reader_vector_u16(&v->pp->p, v->v) + v->slice_i, v->slice_n);
				break;
			case POINTLESS_VECTOR_I32:
				handle = pointless_create_vector_i32_owner(&state->c, pointless_reader_vector_i32(&v->pp->p, v->v) + v->slice_i, v->slice_n);
				break;
			case POINTLESS_VECTOR_U32:
				handle = pointless_create_vector_u32_owner(&state->c, pointless_reader_vector_u32(&v->pp->p, v->v) + v->slice_i, v->slice_n);
				break;
			case POINTLESS_VECTOR_I64:
				handle = pointless_create_vector_i64_owner(&state->c, pointless_reader_vector_i64(&v->pp->p, v->v) + v->slice_i, v->slice_n);
				break;
			case POINTLESS_VECTOR_U64:
				handle = pointless_create_vector_u64_owner(&state->c, pointless_reader_vector_u64(&v->pp->p, v->v) + v->slice_i, v->slice_n);
				break;
			case POINTLESS_VECTOR_FLOAT:
				handle = pointless_create_vector_float_owner(&state->c, pointless_reader_vector_float(&v->pp->p, v->v) + v->slice_i, v->slice_n);
				break;
			case POINTLESS_VECTOR_EMPTY:
				handle = pointless_create_vector_value(&state->c);
				break;
			default:
				state->error_line = __LINE__;
				printf("line: %i\n", __LINE__);
				state->is_error = 1;
				PyErr_SetString(PyExc_ValueError, "internal error: illegal type for primitive vector");
				return POINTLESS_CREATE_VALUE_FAIL;
		}

		RETURN_OOM_IF_FAIL(handle, state);

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

	// python bytearray
	} else if (PyByteArray_Check(py_object)) {
		// create handle and hand over the memory
		Py_ssize_t n_items = PyByteArray_GET_SIZE(py_object);

		if (n_items > UINT32_MAX) {
			PyErr_SetString(PyExc_ValueError, "bytearray has too many items");
			state->error_line = __LINE__;
			printf("line: %i\n", __LINE__);
			state->is_error = 1;
			return POINTLESS_CREATE_VALUE_FAIL;
		}

		handle = pointless_create_vector_u8_owner(&state->c, (uint8_t*)PyByteArray_AS_STRING(py_object), (uint32_t)n_items);
		RETURN_OOM_IF_FAIL(handle, state);

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

	// primitive vectors
	} else if (PyPointlessPrimVector_Check(py_object)) {
		// we just hand over the memory
		PyPointlessPrimVector* prim_vector = (PyPointlessPrimVector*)py_object;
		uint32_t n_items = pointless_dynarray_n_items(&prim_vector->array);
		void* data = prim_vector->array._data;

		switch (prim_vector->type) {
			case POINTLESS_PRIM_VECTOR_TYPE_I8:
				handle = pointless_create_vector_i8_owner(&state->c, (int8_t*)data, n_items);
				break;
			case POINTLESS_PRIM_VECTOR_TYPE_U8:
				handle = pointless_create_vector_u8_owner(&state->c, (uint8_t*)data, n_items);
				break;
			case POINTLESS_PRIM_VECTOR_TYPE_I16:
				handle = pointless_create_vector_i16_owner(&state->c, (int16_t*)data, n_items);
				break;
			case POINTLESS_PRIM_VECTOR_TYPE_U16:
				handle = pointless_create_vector_u16_owner(&state->c, (uint16_t*)data, n_items);
				break;
			case POINTLESS_PRIM_VECTOR_TYPE_I32:
				handle = pointless_create_vector_i32_owner(&state->c, (int32_t*)data, n_items);
				break;
			case POINTLESS_PRIM_VECTOR_TYPE_U32:
				handle = pointless_create_vector_u32_owner(&state->c, (uint32_t*)data, n_items);
				break;
			case POINTLESS_PRIM_VECTOR_TYPE_I64:
				handle = pointless_create_vector_i64_owner(&state->c, (int64_t*)data, n_items);
				break;
			case POINTLESS_PRIM_VECTOR_TYPE_U64:
				handle = pointless_create_vector_u64_owner(&state->c, (uint64_t*)data, n_items);
				break;
			case POINTLESS_PRIM_VECTOR_TYPE_FLOAT:
				handle = pointless_create_vector_float_owner(&state->c, (float*)data, n_items);
				break;
			default:
				PyErr_SetString(PyExc_ValueError, "internal error: illegal type for primitive vector");
				state->error_line = __LINE__;
				printf("line: %i\n", __LINE__);
				state->is_error = 1;
				return POINTLESS_CREATE_VALUE_FAIL;
		}

		RETURN_OOM_IF_FAIL(handle, state);

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

	// unicode object
	} else if (PyUnicode_Check(py_object)) {
		// get it from python
		Py_UNICODE* python_buffer = PyUnicode_AS_UNICODE(py_object);

		// string must not contain zero's
		Py_ssize_t s_len_python = PyUnicode_GET_SIZE(py_object);

		#if Py_UNICODE_SIZE == 4
		uint32_t s_len_pointless = pointless_ucs4_len(python_buffer);
		#else
		uint32_t s_len_pointless = pointless_ucs2_len(python_buffer);
		#endif

		if (s_len_python < 0 || (uint64_t)s_len_python != s_len_pointless) {
			PyErr_SetString(PyExc_ValueError, "unicode string contains a zero, where it shouldn't");
			state->error_line = __LINE__;
			printf("line: %i\n", __LINE__);
			state->is_error = 1;
			return POINTLESS_CREATE_VALUE_FAIL;
		}

		#if Py_UNICODE_SIZE == 4
			if (state->unwiden_strings && pointless_is_ucs4_ascii((uint32_t*)python_buffer))
				handle = pointless_create_string_ucs4(&state->c, python_buffer);
			else
				handle = pointless_create_unicode_ucs4(&state->c, python_buffer);
		#else
			if (state->unwiden_strings && pointless_is_ucs2_ascii(python_buffer))
				handle = pointless_create_string_ucs2(&state->c, python_buffer);
			else
				handle = pointless_create_unicode_ucs2(&state->c, python_buffer);
		#endif

		RETURN_OOM_IF_FAIL(handle, state);

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

	// string object
	} else if (PyString_Check(py_object)) {
		// get it from python
		uint8_t* python_buffer = (uint8_t*)PyString_AS_STRING(py_object);

		// string must not contain zero's
		Py_ssize_t s_len_python = PyString_GET_SIZE(py_object);
		uint32_t s_len_pointless = pointless_ascii_len(python_buffer);

		if (s_len_python < 0 || (uint64_t)s_len_python != s_len_pointless) {
			PyErr_SetString(PyExc_ValueError, "string contains a zero, where it shouldn't");
			state->error_line = __LINE__;
			printf("line: %i\n", __LINE__);
			state->is_error = 1;
			return POINTLESS_CREATE_VALUE_FAIL;
		}

		handle = pointless_create_string_ascii(&state->c, python_buffer);
		RETURN_OOM_IF_FAIL(handle, state);

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

	// dict object
	} else if (PyDict_Check(py_object)) {
		handle = pointless_create_map(&state->c);
		RETURN_OOM_IF_FAIL(handle, state);

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

		PyObject* key = 0;
		PyObject* value = 0;
		Py_ssize_t pos = 0;

		while (PyDict_Next(py_object, &pos, &key, &value)) {
			uint32_t key_handle = pointless_export_py_rec(state, key, depth + 1);
			uint32_t value_handle = pointless_export_py_rec(state, value, depth + 1);

			if (key_handle == POINTLESS_CREATE_VALUE_FAIL || value_handle == POINTLESS_CREATE_VALUE_FAIL)
				break;

			if (pointless_create_map_add(&state->c, handle, key_handle, value_handle) == POINTLESS_CREATE_VALUE_FAIL) {
				PyErr_SetString(PyExc_ValueError, "error adding key/value pair to map");
				state->error_line = __LINE__;
				printf("line: %i\n", __LINE__);
				state->is_error = 1;
				break;
			}
		}

		if (state->is_error) {
			return POINTLESS_CREATE_VALUE_FAIL;
		}

	// set object
	} else if (PyAnySet_Check(py_object)) {
		PyObject* iterator = PyObject_GetIter(py_object);
		PyObject* item = 0;

		if (iterator == 0) {
			printf("line: %i\n", __LINE__);
			state->is_error = 1;
			state->error_line = __LINE__;
			return POINTLESS_CREATE_VALUE_FAIL;
		}

		// get a handle
		handle = pointless_create_set(&state->c);
		RETURN_OOM_IF_FAIL(handle, state);

		// cache object
		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

		// iterate over it
		while ((item = PyIter_Next(iterator)) != 0) {
			uint32_t item_handle = pointless_export_py_rec(state, item, depth + 1);

			if (item_handle == POINTLESS_CREATE_VALUE_FAIL)
				break;

			if (pointless_create_set_add(&state->c, handle, item_handle) == POINTLESS_CREATE_VALUE_FAIL) {
				PyErr_SetString(PyExc_ValueError, "error adding item to set");
				printf("line: %i\n", __LINE__);
				state->is_error = 1;
				state->error_line = __LINE__;
				break;
			}
		}

		Py_DECREF(iterator);

		if (PyErr_Occurred()) {
			printf("line: %i\n", __LINE__);
			state->is_error = 1;
			state->error_line = __LINE__;
			return POINTLESS_CREATE_VALUE_FAIL;
		}

	// bitvector
	} else if (PyPointlessBitvector_Check(py_object)) {
		PyPointlessBitvector* bitvector = (PyPointlessBitvector*)py_object;

		if (bitvector->is_pointless) {
			uint32_t i, n_bits = pointless_reader_bitvector_n_bits(&bitvector->pointless_pp->p, bitvector->pointless_v);
			void* bits = pointless_calloc(ICEIL(n_bits, 8), 1);

			if (bits == 0) {
				RETURN_OOM(state);
			}

			for (i = 0; i < n_bits; i++) {
				if (pointless_reader_bitvector_is_set(&bitvector->pointless_pp->p, bitvector->pointless_v, i))
					bm_set_(bits, i);
			}

			if (state->normalize_bitvector)
				handle = pointless_create_bitvector(&state->c, bits, n_bits);
			else
				handle = pointless_create_bitvector_no_normalize(&state->c, bits, n_bits);
			pointless_free(bits);
			bits = 0;

		} else {
			if (state->normalize_bitvector)
				handle = pointless_create_bitvector(&state->c, bitvector->primitive_bits, bitvector->primitive_n_bits);
			else
				handle = pointless_create_bitvector_no_normalize(&state->c, bitvector->primitive_bits, bitvector->primitive_n_bits);
		}

		RETURN_OOM_IF_FAIL(handle, state);

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

	} else if (PyPointlessSet_Check(py_object)) {
		PyPointlessSet* set = (PyPointlessSet*)py_object;
		const char* error = 0;
		handle = pointless_recreate_value(&set->pp->p, set->v, &state->c, &error);

		if (handle == POINTLESS_CREATE_VALUE_FAIL) {
			printf("line: %i\n", __LINE__);
			state->is_error = 1;
			state->error_line = __LINE__;
			PyErr_Format(PyExc_ValueError, "pointless_recreate_value(): %s", error);
			return POINTLESS_CREATE_VALUE_FAIL;
		}

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

	} else if (PyPointlessMap_Check(py_object)) {
		PyPointlessMap* map = (PyPointlessMap*)py_object;
		const char* error = 0;
		handle = pointless_recreate_value(&map->pp->p, map->v, &state->c, &error);

		if (handle == POINTLESS_CREATE_VALUE_FAIL) {
			printf("line: %i\n", __LINE__);
			state->is_error = 1;
			state->error_line = __LINE__;
			PyErr_Format(PyExc_ValueError, "pointless_recreate_value(): %s", error);
			return POINTLESS_CREATE_VALUE_FAIL;
		}

		if (!pointless_export_set_seen(state, py_object, handle)) {
			RETURN_OOM(state);
		}

	// type not supported
	} else {
		PyErr_Format(PyExc_ValueError, "type <%s> not supported", py_object->ob_type->tp_name);
		state->error_line = __LINE__;
		printf("line: %i\n", __LINE__);
		state->is_error = 1;
	}

	#undef RETURN_OOM
	#undef RETURN_IF_OOM

	return handle;
}
示例#10
0
/** Register native callbacks with Jsonlang VM.
 *
 * Example native_callbacks = { 'name': (('p1', 'p2', 'p3'), func) }
 *
 * May set *ctxs, in which case it should be free()'d by caller.
 *
 * \returns 1 on success, 0 with exception set upon failure.
 */
static int handle_native_callbacks(struct JsonlangVm *vm, PyObject *native_callbacks,
                                   struct NativeCtx **ctxs)
{
    size_t num_natives = 0;
    PyObject *key, *val;
    Py_ssize_t pos = 0;

    if (native_callbacks == NULL) return 1;

    /* Verify the input before we allocate memory, throw all errors at this point.
     * Also, count the callbacks to see how much memory we need.
     */
    while (PyDict_Next(native_callbacks, &pos, &key, &val)) {
        Py_ssize_t i;
        Py_ssize_t num_params;
        PyObject *params;
        const char *key_ = PyString_AsString(key);
        if (key_ == NULL) {
            PyErr_SetString(PyExc_TypeError, "native callback dict keys must be string");
            goto bad;
        }
        if (!PyTuple_Check(val)) {
            PyErr_SetString(PyExc_TypeError, "native callback dict values must be tuples");
            goto bad;
        } else if (PyTuple_Size(val) != 2) {
            PyErr_SetString(PyExc_TypeError, "native callback tuples must have size 2");
            goto bad;
        }
        params = PyTuple_GetItem(val, 0);
        if (!PyTuple_Check(params)) {
            PyErr_SetString(PyExc_TypeError, "native callback params must be a tuple");
            goto bad;
        }
        /* Check the params are all strings */
        num_params = PyTuple_Size(params);
        for (i = 0; i < num_params ; ++i) {
            PyObject *param = PyTuple_GetItem(params, 0);
            if (!PyString_Check(param)) {
                PyErr_SetString(PyExc_TypeError, "native callback param must be string");
                goto bad;
            }
        }
        if (!PyCallable_Check(PyTuple_GetItem(val, 1))) {
            PyErr_SetString(PyExc_TypeError, "native callback must be callable");
            goto bad;
        }

        num_natives++;
        continue;

        bad:
        jsonlang_destroy(vm);
        return 0;
    }

    if (num_natives == 0) {
        return 1;
    }

    *ctxs = malloc(sizeof(struct NativeCtx) * num_natives);
    
    /* Re-use num_natives but just as a counter this time. */
    num_natives = 0;
    pos = 0;
    while (PyDict_Next(native_callbacks, &pos, &key, &val)) {
        Py_ssize_t i;
        Py_ssize_t num_params;
        PyObject *params;
        const char *key_ = PyString_AsString(key);
        params = PyTuple_GetItem(val, 0);
        num_params = PyTuple_Size(params);
        /* Include space for terminating NULL. */
        const char **params_c = malloc(sizeof(const char*) * (num_params + 1));
        for (i = 0; i < num_params ; ++i) {
            params_c[i] = PyString_AsString(PyTuple_GetItem(params, i));
        }
        params_c[num_params] = NULL;
        (*ctxs)[num_natives].vm = vm;
        (*ctxs)[num_natives].callback = PyTuple_GetItem(val, 1);
        (*ctxs)[num_natives].argc = num_params;
        jsonlang_native_callback(vm, key_, cpython_native_callback, &(*ctxs)[num_natives],
                                params_c);
        free(params_c);
        num_natives++;
    }

    return 1;
}
示例#11
0
static struct JsonlangJsonValue *python_to_jsonlang_json(struct JsonlangVm *vm, PyObject *v,
                                                       const char **err_msg)
{
    if (PyString_Check(v)) {
        return jsonlang_json_make_string(vm, PyString_AsString(v));
    } else if (PyUnicode_Check(v)) {
        struct JsonlangJsonValue *r;
        PyObject *str = PyUnicode_AsUTF8String(v);
        r = jsonlang_json_make_string(vm, PyString_AsString(str));
        Py_DECREF(str);
        return r;
    } else if (PyFloat_Check(v)) {
        return jsonlang_json_make_number(vm, PyFloat_AsDouble(v));
    } else if (PyInt_Check(v)) {
        return jsonlang_json_make_number(vm, (double)(PyInt_AsLong(v)));
    } else if (PyBool_Check(v)) {
        return jsonlang_json_make_bool(vm, PyObject_IsTrue(v));
    } else if (v == Py_None) {
        return jsonlang_json_make_null(vm);
    } else if (PySequence_Check(v)) {
        Py_ssize_t len, i;
        struct JsonlangJsonValue *arr;
        // Convert it to a O(1) indexable form if necessary.
        PyObject *fast = PySequence_Fast(v, "python_to_jsonlang_json internal error: not sequence");
        len = PySequence_Fast_GET_SIZE(fast);
        arr = jsonlang_json_make_array(vm);
        for (i = 0; i < len; ++i) {
            struct JsonlangJsonValue *json_el;
            PyObject *el = PySequence_Fast_GET_ITEM(fast, i);
            json_el = python_to_jsonlang_json(vm, el, err_msg);
            if (json_el == NULL) {
                Py_DECREF(fast);
                jsonlang_json_destroy(vm, arr);
                return NULL;
            }
            jsonlang_json_array_append(vm, arr, json_el);
        }
        Py_DECREF(fast);
        return arr;
    } else if (PyDict_Check(v)) {
        struct JsonlangJsonValue *obj;
        PyObject *key, *val;
        Py_ssize_t pos = 0;
        obj = jsonlang_json_make_object(vm);
        while (PyDict_Next(v, &pos, &key, &val)) {
            struct JsonlangJsonValue *json_val;
            const char *key_ = PyString_AsString(key);
            if (key_ == NULL) {
                *err_msg = "Non-string key in dict returned from Python Jsonlang native extension.";
                jsonlang_json_destroy(vm, obj);
                return NULL;
            }
            json_val = python_to_jsonlang_json(vm, val, err_msg);
            if (json_val == NULL) {
                jsonlang_json_destroy(vm, obj);
                return NULL;
            }
            jsonlang_json_object_append(vm, obj, key_, json_val);
        }
        return obj;
    } else {
        *err_msg = "Unrecognized type return from Python Jsonlang native extension.";
        return NULL;
    }
}
示例#12
0
qd_error_t qd_py_to_composed(PyObject *value, qd_composed_field_t *field)
{
    qd_python_check_lock();
    qd_error_clear();
    if (value == Py_None) {
        qd_compose_insert_null(field);
    }
    else if (PyBool_Check(value)) {
        qd_compose_insert_bool(field, PyInt_AS_LONG(value) ? 1 : 0);
    }
    else if (PyInt_Check(value)) {
        qd_compose_insert_long(field, (int64_t) PyInt_AS_LONG(value));
    }
    else if (PyLong_Check(value)) {
        qd_compose_insert_long(field, (int64_t) PyLong_AsLongLong(value));
    }
    else if (PyString_Check(value) || PyUnicode_Check(value)) {
        qd_compose_insert_string(field, PyString_AsString(value));
    }
    else if (PyDict_Check(value)) {
        Py_ssize_t  iter = 0;
        PyObject   *key;
        PyObject   *val;
        qd_compose_start_map(field);
        while (PyDict_Next(value, &iter, &key, &val)) {
            qd_py_to_composed(key, field); QD_ERROR_RET();
            qd_py_to_composed(val, field); QD_ERROR_RET();
        }
        QD_ERROR_PY_RET();
        qd_compose_end_map(field);
    }

    else if (PyList_Check(value)) {
        Py_ssize_t count = PyList_Size(value);
        if (count == 0)
            qd_compose_empty_list(field);
        else {
            qd_compose_start_list(field);
            for (Py_ssize_t idx = 0; idx < count; idx++) {
                PyObject *item = PyList_GetItem(value, idx); QD_ERROR_PY_RET();
                qd_py_to_composed(item, field); QD_ERROR_RET();
            }
            qd_compose_end_list(field);
        }
    }

    else if (PyTuple_Check(value)) {
        Py_ssize_t count = PyTuple_Size(value);
        if (count == 0)
            qd_compose_empty_list(field);
        else {
            qd_compose_start_list(field);
            for (Py_ssize_t idx = 0; idx < count; idx++) {
                PyObject *item = PyTuple_GetItem(value, idx); QD_ERROR_PY_RET();
                qd_py_to_composed(item, field); QD_ERROR_RET();
            }
            qd_compose_end_list(field);
        }
    }
    else {
        PyObject *type=0, *typestr=0, *repr=0;
        if ((type = PyObject_Type(value)) &&
            (typestr = PyObject_Str(type)) &&
            (repr = PyObject_Repr(value)))
            qd_error(QD_ERROR_TYPE, "Can't compose object of type %s: %s",
                     PyString_AsString(typestr), PyString_AsString(repr));
        else
            qd_error(QD_ERROR_TYPE, "Can't compose python object of unknown type");

        Py_XDECREF(type);
        Py_XDECREF(typestr);
        Py_XDECREF(repr);
    }
    return qd_error_code();
}
示例#13
0
static int
_rrdtool_fetch_cb_wrapper(
    const char *filename,
    enum cf_en cf_idx,
    time_t *start,
    time_t *end,
    unsigned long *step,
    unsigned long *ds_cnt,
    char ***ds_namv,
    rrd_value_t **data)
{
    PyObject *args;
    PyObject *kwargs;
    PyObject *ret = NULL;
    PyObject *tmp;
    PyObject *tmp_min_ts;
    PyGILState_STATE gstate;
    Py_ssize_t rowcount = 0;
    int rc = -1;
    unsigned int i, ii;

    gstate = PyGILState_Ensure();

    if (_rrdtool_fetch_callable == NULL) {
        rrd_set_error("use rrdtool.register_fetch_cb to register a fetch callback");
        goto gil_release_err;
    }

    args = PyTuple_New(0);
    kwargs = PyDict_New();

    /* minimum possible UNIX datetime */
    tmp_min_ts = PyLong_FromLong(0);

    PyObject *po_filename = PyRRD_String_FromString(filename);
    PyDict_SetItemString(kwargs, "filename", po_filename);
    Py_DECREF(po_filename);

    PyObject *po_cfstr = PyRRD_String_FromString(PyRRD_String_FromCF(cf_idx));
    PyDict_SetItemString(kwargs, "cf", po_cfstr);
    Py_DECREF(po_cfstr);

    PyObject *po_start = PyLong_FromLong(*start);
    PyDict_SetItemString(kwargs, "start", po_start);
    Py_DECREF(po_start);

    PyObject *po_end = PyLong_FromLong(*end);
    PyDict_SetItemString(kwargs, "end", po_end);
    Py_DECREF(po_end);

    PyObject *po_step = PyLong_FromUnsignedLong(*step);
    PyDict_SetItemString(kwargs, "step", po_step);
    Py_DECREF(po_step);

    /* execute Python callback method */
    ret = PyObject_Call(_rrdtool_fetch_callable, args, kwargs);
    Py_DECREF(args);
    Py_DECREF(kwargs);

    if (ret == NULL) {
        rrd_set_error("calling python callback failed");
        goto gil_release_err;
    }

    /* handle return value of callback */
    if (!PyDict_Check(ret)) {
        rrd_set_error("expected callback method to be a dict");
        goto gil_release_err;
    }

    tmp = PyDict_GetItemString(ret, "step");
    if (tmp == NULL) {
        rrd_set_error("expected 'step' key in callback return value");
        goto gil_release_err;
    } else if (!PyRRD_Long_Check(tmp)) {
        rrd_set_error("the 'step' key in callback return value must be int");
        goto gil_release_err;
    } else
        *step = PyLong_AsLong(tmp);

    tmp = PyDict_GetItemString(ret, "start");
    if (tmp == NULL) {
        rrd_set_error("expected 'start' key in callback return value");
        goto gil_release_err;
    } else if (!PyRRD_Long_Check(tmp)) {
        rrd_set_error("expected 'start' key in callback return value to be "
            "of type int");
        goto gil_release_err;
    } else if (PyObject_RichCompareBool(tmp, tmp_min_ts, Py_EQ) || 
               PyObject_RichCompareBool(tmp, po_start, Py_LT)) {
        rrd_set_error("expected 'start' value in callback return dict to be "
            "equal or earlier than passed start timestamp");
        goto gil_release_err;
    } else {
        *start = PyLong_AsLong(po_start);

        if (*start == -1) {
            rrd_set_error("expected 'start' value in callback return value to"
                " not exceed LONG_MAX");
            goto gil_release_err;
        }
    }

    tmp = PyDict_GetItemString(ret, "data");
    if (tmp == NULL) {
        rrd_set_error("expected 'data' key in callback return value");
        goto gil_release_err;
    } else if (!PyDict_Check(tmp)) {
        rrd_set_error("expected 'data' key in callback return value of type "
            "dict");
        goto gil_release_err;
    } else {
        *ds_cnt = (unsigned long)PyDict_Size(tmp);
        *ds_namv = (char **)calloc(*ds_cnt, sizeof(char *));

        if (*ds_namv == NULL) {
            rrd_set_error("an error occured while allocating memory for "
                "ds_namv when allocating memory for python callback");
            goto gil_release_err;
        }

        PyObject *key, *value;
        Py_ssize_t pos = 0;  /* don't use pos for indexing */
        unsigned int x = 0;

        while (PyDict_Next(tmp, &pos, &key, &value)) {
            char *key_str = PyRRD_String_AS_STRING(key);

            if (key_str == NULL) {
                rrd_set_error("key of 'data' element from callback return "
                    "value is not a string");
                goto gil_release_free_dsnamv_err;
            } else if (strlen(key_str) > DS_NAM_SIZE) {
                rrd_set_error("key '%s' longer than the allowed maximum of %d "
                    "byte", key_str, DS_NAM_SIZE - 1);
                goto gil_release_free_dsnamv_err;
            }

            if ((((*ds_namv)[x]) = (char *)malloc(sizeof(char) * DS_NAM_SIZE)) == NULL) {
                rrd_set_error("malloc fetch ds_namv entry");
                goto gil_release_free_dsnamv_err;
            }

            strncpy((*ds_namv)[x], key_str, DS_NAM_SIZE - 1);
            (*ds_namv)[x][DS_NAM_SIZE - 1] = '\0';

            if (!PyList_Check(value)) {
                rrd_set_error("expected 'data' dict values in callback return "
                    "value of type list");
                goto gil_release_free_dsnamv_err;
            } else if (PyList_Size(value) > rowcount)
                rowcount = PyList_Size(value);

            ++x;
        }

        *end = *start + *step * rowcount;

        if (((*data) = (rrd_value_t *)malloc(*ds_cnt * rowcount * sizeof(rrd_value_t))) == NULL) {
            rrd_set_error("malloc fetch data area");
            goto gil_release_free_dsnamv_err;
        }

        for (i = 0; i < *ds_cnt; i++) {
            for (ii = 0; ii < (unsigned int)rowcount; ii++) {
                char *ds_namv_i = (*ds_namv)[i];
                double va;
                PyObject *lstv = PyList_GetItem(PyDict_GetItemString(tmp, ds_namv_i), ii);

                /* lstv may be NULL here in case an IndexError has been raised;
                   in such case the rowcount is higher than the number of elements for
                   the list of that ds. use DNAN as value for these then */
                if (lstv == NULL || lstv == Py_None) {
                    if (lstv == NULL)
                        PyErr_Clear();
                    va = DNAN;
                }
                else {
                    va = PyFloat_AsDouble(lstv);
                    if (va == -1.0 && PyErr_Occurred()) {
                        PyObject *exc_type, *exc_value, *exc_value_str = NULL, *exc_tb;
                        PyErr_Fetch(&exc_type, &exc_value, &exc_tb);

                        if (exc_value != NULL) {
                            exc_value_str = PyObject_Str(exc_value);
                            char *exc_str = PyRRD_String_AS_STRING(exc_value_str);
                            rrd_set_error(exc_str);
                            Py_DECREF(exc_value);
                        }

                        Py_DECREF(exc_type);
                        Py_DECREF(exc_value_str);
                        if (exc_tb != NULL)
                            Py_DECREF(exc_tb);
                        goto gil_release_free_dsnamv_err;
                    }
                }

                (*data)[i + ii * (*ds_cnt)] = va;
            }
        }
    }

    /* success */
    rc = 1;
    goto gil_release;

gil_release_free_dsnamv_err:
    for (i = 0; i < *ds_cnt; i++) {
        if ((*ds_namv)[i]) {
            free((*ds_namv)[i]);
        }
    }

    free(*ds_namv);

gil_release_err:
    rc = -1;

gil_release:
    if (ret != NULL)
        Py_DECREF(ret);
    PyGILState_Release(gstate);
    return rc;
}
示例#14
0
static PyObject *
Process_func_spawn(PyObject *cls, PyObject *args, PyObject *kwargs)
{
    int err, flags, stdio_count;
    unsigned int uid, gid;
    Py_ssize_t i, n, pos, size;
    PyObject *key, *value, *item, *tmp, *callback, *arguments, *env, *stdio, *ret, *executable, *cwd;
    Process *self;
    Loop *loop;
    uv_process_options_t options;
    uv_stdio_container_t *stdio_container;

    static char *kwlist[] = {"loop", "args", "executable", "env", "cwd", "uid", "gid", "flags", "stdio", "exit_callback", NULL};

    cwd = executable = Py_None;
    tmp = arguments = env = stdio = NULL;
    stdio_container = NULL;
    flags = uid = gid = stdio_count = 0;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O|OO!OIIiOO:__init__", kwlist, &LoopType, &loop, &arguments, &executable, &PyDict_Type, &env, &cwd, &uid, &gid, &flags, &stdio, &callback)) {
        return NULL;
    }

    if (callback != Py_None && !PyCallable_Check(callback)) {
        PyErr_SetString(PyExc_TypeError, "a callable is required");
        return NULL;
    }

    if (!PyBytes_Check(arguments) && !PyUnicode_Check(arguments) && !PySequence_Check(arguments)) {
        PyErr_SetString(PyExc_TypeError, "only string or iterable objects are supported for 'args'");
        return NULL;
    }

    if (stdio && !PySequence_Check(stdio)) {
        PyErr_SetString(PyExc_TypeError, "only iterable objects are supported for 'stdio'");
        return NULL;
    }

    self = (Process *)Process_tp_new((PyTypeObject *) cls, args, kwargs);
    if (!self) {
        return NULL;
    }

    initialize_handle(HANDLE(self), loop);
    /* Don't consider the handle initialized until uv_spawn is called. Unline other handles,
     * there is no uv_process_init, it's called at the begining of uv_spawn, so don't
     * consider the handle initialized until then, or we'd call uv_close when the Python
     * object is deallocated, which is not A Good Thing (TM).
     */
    HANDLE(self)->initialized = False;

    memset(&options, 0, sizeof(uv_process_options_t));

    options.uid = uid;
    options.gid = gid;
    options.flags = flags;
    options.exit_cb = pyuv__process_exit_cb;

    /* process args */

    if (PyBytes_Check(arguments) || PyUnicode_Check(arguments)) {
        options.args = PyMem_Malloc(sizeof *(options.args) * 2);
        if (!options.args) {
            PyErr_NoMemory();
            goto error;
        }
        options.args[0] = pyuv_dup_strobj(arguments);
        if (!options.args[0]) {
            goto error;
        }
        options.args[1] = NULL;
    } else {
        /* it's a sequence object */
        n = PySequence_Length(arguments);
        if (n < 1) {
            PyErr_SetString(PyExc_ValueError, "'args' must contain at least one element");
            goto error;
        }
        options.args = PyMem_Malloc(sizeof *(options.args) * (n + 1));
        if (!options.args) {
            PyErr_NoMemory();
            goto error;
        }
        for (i = 0; i < n; i++) {
            item = PySequence_GetItem(arguments, i);
            if (!item) {
                options.args[i] = NULL;
                goto error;
            }
            options.args[i] = pyuv_dup_strobj(item);
            if (!options.args[i]) {
                Py_DECREF(item);
                goto error;
            }
            Py_DECREF(item);
        }
        options.args[n] = NULL;
    }

    /* process file */

    if (executable != Py_None) {
        options.file = pyuv_dup_strobj(executable);
        if (!options.file) {
            goto error;
        }
    } else {
        size = strlen(options.args[0]) + 1;
        options.file = PyMem_Malloc(size);
        if (!options.file) {
            PyErr_NoMemory();
            goto error;
        }
        memcpy((void*)options.file, options.args[0], size);
    }

    /* process cwd */
    if (cwd != Py_None) {
        options.cwd = pyuv_dup_strobj(cwd);
        if (!options.cwd) {
            goto error;
        }
    }

    /* process env */

    if (env) {
        char *key_str, *value_str;
        PyObject *key_bytes, *value_bytes;
        n = PyDict_Size(env);
        if (n > 0) {
            options.env = PyMem_Malloc(sizeof *(options.env) * (n + 1));
            if (!options.env) {
                PyErr_NoMemory();
                goto error;
            }
            i = 0;
            pos = 0;
            while (PyDict_Next(env, &pos, &key, &value)) {
                key_bytes = value_bytes = NULL;
                if (!pyuv_PyUnicode_FSConverter(key, &key_bytes)) {
                    options.env[i] = NULL;
                    goto error;
                }
                if (!pyuv_PyUnicode_FSConverter(value, &value_bytes)) {
                    Py_DECREF(key_bytes);
                    options.env[i] = NULL;
                    goto error;
                }
                key_str = PyBytes_AS_STRING(key_bytes);
                value_str = PyBytes_AS_STRING(value_bytes);
                size = PyBytes_GET_SIZE(key_bytes) + PyBytes_GET_SIZE(value_bytes) + 2;
                options.env[i] = PyMem_Malloc(size);
                if (!options.env[i]) {
                    options.env[i] = NULL;
                    PyErr_NoMemory();
                    Py_DECREF(key_bytes);
                    Py_DECREF(value_bytes);
                    goto error;
                }
                PyOS_snprintf(options.env[i], size, "%s=%s", key_str, value_str);
                Py_DECREF(key_bytes);
                Py_DECREF(value_bytes);
                i++;
            }
            options.env[i] = NULL;
        }
    }

    /* process stdio container */

    if (stdio) {
        n = PySequence_Length(stdio);
        stdio_container = PyMem_Malloc(sizeof *stdio_container * n);
        if (!stdio_container) {
            PyErr_NoMemory();
            goto error;
        }
        item = NULL;
        for (i = 0;i < n; i++) {
            item = PySequence_GetItem(stdio, i);
            if (!item || !PyObject_TypeCheck(item, &StdIOType)) {
                Py_XDECREF(item);
                PyErr_SetString(PyExc_TypeError, "a StdIO instance is required");
                goto error;
            }
            stdio_count++;
            stdio_container[i].flags = ((StdIO *)item)->flags;
            if (((StdIO *)item)->flags & (UV_CREATE_PIPE | UV_INHERIT_STREAM)) {
                stdio_container[i].data.stream = (uv_stream_t *)(UV_HANDLE(((StdIO *)item)->stream));
            } else if (((StdIO *)item)->flags & UV_INHERIT_FD) {
                stdio_container[i].data.fd = ((StdIO *)item)->fd;
            }
            Py_DECREF(item);
        }
    }
    options.stdio = stdio_container;
    options.stdio_count = stdio_count;

    HANDLE(self)->initialized = True;

    err = uv_spawn(UV_HANDLE_LOOP(self), &self->process_h, &options);
    if (err < 0) {
        RAISE_UV_EXCEPTION(err, PyExc_ProcessError);
        goto error;
    }

    ret = (PyObject *) self;

    tmp = (PyObject *)self->on_exit_cb;
    Py_INCREF(callback);
    self->on_exit_cb = callback;
    Py_XDECREF(tmp);

    tmp = self->stdio;
    Py_XINCREF(stdio);
    self->stdio = stdio;
    Py_XDECREF(tmp);

    /* Increase refcount so that object is not removed before the exit callback is called */
    Py_INCREF(self);

    goto cleanup;

error:
    ret = NULL;
    Py_DECREF(self);

cleanup:
    if (options.args) {
        for (i = 0; options.args[i] != NULL; ++i) {
            PyMem_Free(options.args[i]);
        }
        PyMem_Free(options.args);
    }

    if (options.env) {
        for (i = 0; options.env[i] != NULL; ++i) {
            PyMem_Free(options.env[i]);
        }
        PyMem_Free(options.env);
    }

    PyMem_Free((void*)options.cwd);
    PyMem_Free((void*)options.file);
    PyMem_Free(options.stdio);

    return ret;
}
示例#15
0
// This is the helper for QObject.pyqtConfigure().
int qpycore_pyqtconfigure(PyObject *self, QObject *qobj, PyObject *kwds)
{
    PyObject *name_obj, *value_obj;
    SIP_SSIZE_T pos = 0;
    const QMetaObject *mo = qobj->metaObject();
    QByteArray unknown_name;

    while (PyDict_Next(kwds, &pos, &name_obj, &value_obj))
    {
        // Get the name encoded name.
        PyObject *enc_name_obj = name_obj;
        const char *name = sipString_AsASCIIString(&enc_name_obj);

        if (!name)
            return -1;

        QByteArray enc_name(name);
        Py_DECREF(enc_name_obj);

        // See if it is a property.
        int idx = mo->indexOfProperty(enc_name.constData());

        if (idx >= 0)
        {
            QMetaProperty prop = mo->property(idx);

            // A negative type means a QVariant property.
            if (prop.userType() >= 0)
            {
                const Chimera *ct = Chimera::parse(prop);

                if (!ct)
                {
                    PyErr_Format(PyExc_TypeError,
                            "'%s' keyword argument has an invalid type",
                            enc_name.constData());

                    return -1;
                }

                QVariant value;
                bool valid = ct->fromPyObject(value_obj, &value);

                delete ct;

                if (!valid)
                    return -1;

                qobj->setProperty(enc_name.constData(), value);
            }
            else
            {
                int value_state, iserr = 0;

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

                if (iserr)
                    return -1;

                qobj->setProperty(enc_name.constData(), *value);

                sipReleaseType(value, sipType_QVariant, value_state);
            }
        }
        else
        {
            bool unknown = true;

            // See if it is a signal.
            PyObject *sig = PyObject_GetAttr(self, name_obj);

            if (sig)
            {
                if (PyObject_IsInstance(sig, (PyObject *)&qpycore_pyqtBoundSignal_Type))
                {
                    static PyObject *connect_obj = NULL;

                    if (!connect_obj)
                    {
#if PY_MAJOR_VERSION >= 3
                        connect_obj = PyUnicode_FromString("connect");
#else
                        connect_obj = PyString_FromString("connect");
#endif

                        if (!connect_obj)
                        {
                            Py_DECREF(sig);
                            return -1;
                        }
                    }

                    // Connect the slot.
                    PyObject *res = PyObject_CallMethodObjArgs(sig,
                            connect_obj, value_obj, 0);

                    if (!res)
                    {
                        Py_DECREF(sig);
                        return -1;
                    }

                    Py_DECREF(res);

                    unknown = false;
                }

                Py_DECREF(sig);
            }

            if (unknown)
                // Remember there is an exception but carry on with the
                // remaining names.  This supports the use case where a name
                // might not be valid in a particular context, but isn't a
                // problem.
                unknown_name = enc_name;
        }
    }

    if (!unknown_name.isEmpty())
    {
        PyErr_Format(PyExc_AttributeError,
                "'%s' is not a Qt property or a signal",
                unknown_name.constData());

        return -1;
    }

    return 0;
}
示例#16
0
int lightblueobex_addheaders(obex_t *obex, PyObject *headers, obex_object_t *obj)
{
    uint8_t hi;
    obex_headerdata_t hv;
    PyObject *key, *value;
    Py_ssize_t pos = 0;
    int r = -1;

    DEBUG("%s()\n", __func__);

    if (headers == NULL || !PyDict_Check(headers)) {
        DEBUG("\taddheaders() arg must be dict\n");
        return -1;
    }

    /* add connection-id first */
    key = PyInt_FromLong(OBEX_HDR_CONNECTION);
    if (key != NULL) {
        value = PyDict_GetItem(headers, key);   /* don't decref! */
        Py_DECREF(key);
        key = NULL;
        if (value != NULL) {
            DEBUG("\tadding connection-id\n");
            r = lightblueobex_add4byteheader(obex, obj, OBEX_HDR_CONNECTION,
                    value);
            if (r < 0) {
                DEBUG("\terror adding connection-id header\n");
                return -1;
            }
        }
    }

    /* add target header first (shouldn't have both conn-id and target) */
    key = PyInt_FromLong(OBEX_HDR_TARGET);
    if (key != NULL) {
        value = PyDict_GetItem(headers, key);   /* don't decref! */
        Py_DECREF(key);
        key = NULL;
        if (value != NULL) {
            DEBUG("\tadding target\n");
            r = lightblueobex_addbytestreamheader(obex, obj, OBEX_HDR_TARGET,
                    value);
            if (r < 0) {
                DEBUG("\terror adding target header\n");
                return -1;
            }
        }
    }

    while (PyDict_Next(headers, &pos, &key, &value)) {
        if (key == NULL || value == NULL) {
            DEBUG("\terror reading headers dict\n");
            return -1;
        }
        if (!PyInt_Check(key)) {
            DEBUG("\theader id must be int, was %s\n", key->ob_type->tp_name);
            return -1;
        }

        hi = (uint8_t)PyInt_AsUnsignedLongMask(key);
        if (hi == OBEX_HDR_CONNECTION || hi == OBEX_HDR_TARGET) {
            /* these are already added */
            continue;
        }

        DEBUG("\tadding header: 0x%02x\n", hi);

        switch (hi & OBEX_HI_MASK) {
        case OBEX_UNICODE:
        {
            PyObject *encoded = NULL;
            if (PyUnicode_Check(value)) {
                encoded = PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(value),
                        PyUnicode_GET_SIZE(value),
                        NULL, OBEX_BIG_ENDIAN);
            } else {
                /* try converting to unicode */
                PyObject *tmp = NULL;
                tmp = PyUnicode_FromObject(value);
                if (tmp == NULL) {
                    if (PyErr_Occurred()) {
                        PyErr_Print();
                        PyErr_Clear();  /* let caller set exception */
                    }
                    DEBUG("\tfailed to convert header value for id 0x%02x to unicode\n", hi);
                    return -1;
                }
                encoded = PyUnicode_EncodeUTF16(PyUnicode_AS_UNICODE(tmp),
                        PyUnicode_GET_SIZE(tmp),
                        NULL, OBEX_BIG_ENDIAN);
                Py_DECREF(tmp);
            }
            if (encoded == NULL) {
                if (PyErr_Occurred()) {
                    PyErr_Print();
                    PyErr_Clear();  /* let caller set exception */
                }
                DEBUG("\tfailed to encode value for header 0x%02x to UTF-16 big endian\n", hi);
                return -1;
            }
            r = lightblueobex_addunicodeheader(obex, obj, hi, encoded);
            Py_DECREF(encoded);
            break;
        }
        case OBEX_BYTE_STREAM:
        {
            r = lightblueobex_addbytestreamheader(obex, obj, hi, value);
            break;
        }
        case OBEX_BYTE:
        {
            long intvalue;
            if (!PyInt_Check(value)) {
                DEBUG("\theader value for id 0x%02x must be int, was %s\n",
                    hi, value->ob_type->tp_name);
                return -1;
            }
            intvalue = PyInt_AsLong(value);
            if (PyErr_Occurred()) {
                DEBUG("\terror reading int value for 0x%02x\n", hi);
                PyErr_Clear();
                return -1;
            }
            hv.bq1 = (uint8_t)intvalue;
            r = OBEX_ObjectAddHeader(obex, obj, hi, hv, 1,
                    OBEX_FL_FIT_ONE_PACKET);
            break;
        }
        case OBEX_INT:
        {
            r = lightblueobex_add4byteheader(obex, obj, hi, value);
            break;
        }
        default:
            DEBUG("\tunknown header id encoding %d\n", (hi & OBEX_HI_MASK));
            return -1;
        }
        if (r < 0) {
            DEBUG("\terror adding header 0x%02x\n", hi);
            return -1;
        }
    }

    return 1;
}
示例#17
0
int ObjectRow_PyObject__init(ObjectRow_PyObject *self, PyObject *args, PyObject *kwargs)
{
    PyObject *pytmp, *pydesc, *cursor, *row, *o_type, *pickle_dict = 0;
    struct module_state *mstate;
    if (!PyArg_ParseTuple(args, "OO|O!", &cursor, &row, &PyDict_Type, &pickle_dict))
        return -1;

    mstate = GETSTATE_FROMTYPE(self);
    if (pickle_dict) {
        /* If row or cursor weren't specified, then we require the third arg
         * (pickle_dict) be a dictionary, and we basically behave as this dict.
         * We do this for example from Database.add()
         */
        self->pickle = pickle_dict;
        Py_INCREF(self->pickle);
        self->row = Py_None;
        Py_INCREF(self->row);
        self->desc = Py_None;
        Py_INCREF(self->desc);
        return 0;
    }

    /* First argument is the db cursor from which we fetch the row description
     * and object types.  Or, it is a 2-tuple of same.
     */
    if (PyTuple_Check(cursor)) {
        self->desc = PySequence_GetItem(cursor, 0); // new ref
        self->object_types = PySequence_GetItem(cursor, 1); // new ref
    } else if (!PyObject_HasAttrString(cursor, "_db")) {
        PyErr_Format(PyExc_ValueError, "First argument is not a Cursor or tuple object");
        return -1;
    } else {
        PyObject *weak_db = PyObject_GetAttrString(cursor, "_db"); // new ref
        PyObject *db = PyWeakref_GetObject(weak_db); // borrowed ref
        self->object_types = PyObject_GetAttrString(db, "_object_types"); // new ref
        self->desc = PyObject_GetAttrString(cursor, "description"); // new ref
        Py_XDECREF(weak_db);
    }

    self->row = row;

    self->type_name = PySequence_GetItem(row, 0); // new ref
    if (!PyString_Check(self->type_name) && !PyUnicode_Check(self->type_name)) {
        Py_XDECREF(self->desc);
        Py_XDECREF(self->object_types);
        PyErr_Format(PyExc_ValueError, "First element of row must be object type");
        return -1;
    }

    o_type = PyDict_GetItem(self->object_types, self->type_name); // borrowed ref
    self->attrs = PySequence_GetItem(o_type, 1); // new ref
    if (!self->attrs) {
        char *type_name;
#if PY_MAJOR_VERSION >= 3
        PyObject *bytes = PyUnicode_AsUTF8String(self->type_name);
        type_name = strdup(PyBytes_AS_STRING(bytes));
        Py_DECREF(bytes);
#else
        type_name = strdup(PyString_AsString(self->type_name));
#endif
        PyErr_Format(PyExc_ValueError, "Object type '%s' not defined.", type_name);
        free(type_name);
        Py_XDECREF(self->desc);
        Py_XDECREF(self->object_types);
        return -1;
    }

    /* For the queries dict key we use the address of the desc object rather
     * than the desc itself.  desc is a tuple, and if we use it as a key it
     * will result in a hash() on the desc for each row which is much more
     * expensive.  pysqlite passes us the same description tuple object for
     * each row in a query so it is safe to use the address.
     */
    pydesc = PyLong_FromVoidPtr(self->desc);
    pytmp = PyDict_GetItem(mstate->queries, pydesc);
    self->query_info = pytmp ? (QueryInfo *)PyCObject_AsVoidPtr(pytmp) : NULL;
    if (!self->query_info) {
        /* This is a row for a query we haven't seen before, so we need to do
         * some initial setup.  Most of what we do here is convert row and
         * attribute metadata into convenient data structures for later access.
         */

        PyObject **desc_tuple = PySequence_Fast_ITEMS(self->desc);
        PyObject *key, *value;
        int i = 0;
        Py_ssize_t pos = 0;

        self->query_info = (QueryInfo *)malloc(sizeof(QueryInfo));
        self->query_info->refcount = 0;
        self->query_info->pickle_idx = -1;
        self->query_info->idxmap = PyDict_New();

        /* Iterate over the columns from the SQL query and keep track of
         * attribute names and their indexes within the row tuple.  Start at
         * index 2 because index 0 and 1 are internal (the object type name
         * literal and type id).
         */
        for (i = 2; i < PySequence_Length(self->desc); i++) {
            PyObject **desc_col = PySequence_Fast_ITEMS(desc_tuple[i]);
            ObjectAttribute *attr = (ObjectAttribute *)malloc(sizeof(ObjectAttribute));

            attr->pickled = 0;
            attr->index = i;
            if (PyStr_Compare(desc_col[0], "pickle") == 0)
                self->query_info->pickle_idx = i;

            pytmp = PyCObject_FromVoidPtr(attr, free);
            PyDict_SetItem(self->query_info->idxmap, desc_col[0], pytmp);
            Py_DECREF(pytmp);
        }

        /* Now iterate over the kaa.db object attribute dict, storing the
         * type of each attribute, its flags, and figure out whether or not
         * we need to look in the pickle for that attribute.
         */
        while (PyDict_Next(self->attrs, &pos, &key, &value)) {
            pytmp = PyDict_GetItem(self->query_info->idxmap, key);
            ObjectAttribute *attr = pytmp ? (ObjectAttribute *)PyCObject_AsVoidPtr(pytmp) : NULL;

            if (!attr) {
                attr = (ObjectAttribute *)malloc(sizeof(ObjectAttribute));
                attr->index = -1;
                pytmp = PyCObject_FromVoidPtr(attr, free);
                PyDict_SetItem(self->query_info->idxmap, key, pytmp);
                Py_DECREF(pytmp);
            }
            attr->type = PySequence_Fast_GET_ITEM(value, 0);
            attr->flags = PyInt_AsLong(PySequence_Fast_GET_ITEM(value, 1));
            attr->named_ivtidx = PyObject_RichCompareBool(PySequence_Fast_GET_ITEM(value, 2), key, Py_EQ) == 1;
            if (IS_ATTR_INDEXED_IGNORE_CASE(attr->flags) || attr->flags & ATTR_SIMPLE)
                // attribute is set to ignore case, or it's ATTR_SIMPLE, so we
                // need to look in the pickle for this attribute.
                attr->pickled = 1;
            else
                attr->pickled = 0;
        }

        /* Create a hash table that maps object type ids to type names.
         */
        pos = 0;
        self->query_info->type_names = PyDict_New();
        while (PyDict_Next(self->object_types, &pos, &key, &value)) {
            PyObject *type_id = PySequence_Fast_GET_ITEM(value, 0);
            PyDict_SetItem(self->query_info->type_names, type_id, key);
        }
        pytmp = PyCObject_FromVoidPtr(self->query_info, NULL);
        PyDict_SetItem(mstate->queries, pydesc, pytmp);
        Py_DECREF(pytmp);
    }
    Py_DECREF(pydesc);

    self->query_info->refcount++;
    if (self->query_info->pickle_idx >= 0) {
        // Pickle column included in row.  Set _pickle member to True which
        // indicates the pickle data was fetched, but just hasn't yet been
        // unpickled.
        if (PySequence_Fast_GET_ITEM(self->row, self->query_info->pickle_idx) != Py_None)
            self->has_pickle = 1;
        self->pickle = Py_True;
    } else
        self->pickle = Py_False;

    Py_INCREF(self->pickle);
    Py_INCREF(self->row);

    if (pickle_dict && pickle_dict != Py_None) {
        Py_DECREF(self->pickle);
        self->pickle = pickle_dict;
        Py_INCREF(self->pickle);
        self->has_pickle = self->unpickled = 1;
    }
    return 0;
}
Config* PyGLPSParse2Config(PyObject *, PyObject *args, PyObject *kws)
{
    PyObject *conf = NULL, *extra_defs = Py_None;
    const char *path = NULL;
    const char *pnames[] = {"config", "path", "extra", NULL};
    if(!PyArg_ParseTupleAndKeywords(args, kws, "O|zO", (char**)pnames, &conf, &path, &extra_defs))
        return NULL;

    GLPSParser parser;

    if(extra_defs==Py_None) {
        // no-op
    } else if(PyDict_Check(extra_defs)) {
        PyObject *key, *value;
        Py_ssize_t pos = 0;

        while(PyDict_Next(extra_defs, &pos, &key, &value)) {
            PyRef<> keyx(key, borrow());
            PyCString keystr(keyx);

            Config::value_t curval;

            if(PyNumber_Check(value)) {
                PyRef<> pyf(PyNumber_Float(value));
                curval = PyFloat_AsDouble(pyf.py());

            } else if(PyString_Check(value)) {
                PyRef<> valuex(value, borrow());
                PyCString valstr(valuex);

                curval = valstr.c_str();

            } else {
                PyErr_SetString(PyExc_ValueError, "extra {} can contain only numbers or strings");
                return NULL;
            }

            parser.setVar(keystr.c_str(), curval);
        }
    } else {
        PyErr_SetString(PyExc_ValueError, "'extra' must be a dict");
        return NULL;
    }

    PyGetBuf buf;
    std::auto_ptr<Config> C;

    PyRef<> listref;

    if(PyObject_HasAttrString(conf, "read")) { // file-like
        PyCString pyname;

        if(!path && PyObject_HasAttrString(conf, "name")) {
            path = pyname.c_str(pydirname(PyObject_GetAttrString(conf, "name")));
        }

        PyRef<> pybytes(PyObject_CallMethod(conf, "read", ""));
        if(!buf.get(pybytes.py())) {
            PyErr_SetString(PyExc_TypeError, "read() must return a buffer");
            return NULL;
        }
        C.reset(parser.parse_byte((const char*)buf.data(), buf.size(), path));

    } else if(buf.get(conf)) {
        C.reset(parser.parse_byte((const char*)buf.data(), buf.size(), path));

#if PY_MAJOR_VERSION >= 3
    } else if(PyUnicode_Check(conf)) { // py3 str (aka unicode) doesn't implement buffer iface
        PyCString buf;
        const char *cbuf = buf.c_str(conf);

        C.reset(parser.parse_byte(cbuf, strlen(cbuf), path));
#endif

    } else {
        if(PyDict_Check(conf)) {
            listref.reset(PyMapping_Items(conf));
            conf = listref.py();
        }
        if(PyList_Check(conf)) {
            C.reset(list2conf(conf));

        } else {
            throw std::invalid_argument("'config' must be dict, list of tuples, or byte buffer");
        }
    }

    return C.release();
}
示例#19
0
void
_PyModule_Clear(PyObject *m)
{
    /* To make the execution order of destructors for global
       objects a bit more predictable, we first zap all objects
       whose name starts with a single underscore, before we clear
       the entire dictionary.  We zap them by replacing them with
       None, rather than deleting them from the dictionary, to
       avoid rehashing the dictionary (to some extent). */

    Py_ssize_t pos;
    PyObject *key, *value;
    PyObject *d;

    d = ((PyModuleObject *)m)->md_dict;
    if (d == NULL)
        return;

    /* First, clear only names starting with a single underscore */
    pos = 0;
    while (PyDict_Next(d, &pos, &key, &value)) {
        if (value != Py_None && PyUnicode_Check(key)) {
            Py_UNICODE *u = PyUnicode_AS_UNICODE(key);
            if (u[0] == '_' && u[1] != '_') {
                if (Py_VerboseFlag > 1) {
                    const char *s = _PyUnicode_AsString(key);
                    if (s != NULL)
                        PySys_WriteStderr("#   clear[1] %s\n", s);
                    else
                        PyErr_Clear();
                }
                PyDict_SetItem(d, key, Py_None);
            }
        }
    }

    /* Next, clear all names except for __builtins__ */
    pos = 0;
    while (PyDict_Next(d, &pos, &key, &value)) {
        if (value != Py_None && PyUnicode_Check(key)) {
            Py_UNICODE *u = PyUnicode_AS_UNICODE(key);
            if (u[0] != '_'
                || PyUnicode_CompareWithASCIIString(key, "__builtins__") != 0)
            {
                if (Py_VerboseFlag > 1) {
                    const char *s = _PyUnicode_AsString(key);
                    if (s != NULL)
                        PySys_WriteStderr("#   clear[2] %s\n", s);
                    else
                        PyErr_Clear();
                }
                PyDict_SetItem(d, key, Py_None);
            }
        }
    }

    /* Note: we leave __builtins__ in place, so that destructors
       of non-global objects defined in this module can still use
       builtins, in particularly 'None'. */

}
示例#20
0
/* Enter the final scope information into the st_symbols dict. 
 * 
 * All arguments are dicts.  Modifies symbols, others are read-only.
*/
static int
update_symbols(PyObject *symbols, PyObject *scope, 
               PyObject *bound, PyObject *free, int classflag)
{
	PyObject *name, *v, *u, *w, *free_value = NULL;
	Py_ssize_t pos = 0;

	while (PyDict_Next(symbols, &pos, &name, &v)) {
		long i, flags;
		assert(PyInt_Check(v));
		flags = PyInt_AS_LONG(v);
		w = PyDict_GetItem(scope, name);
		assert(w && PyInt_Check(w));
		i = PyInt_AS_LONG(w);
		flags |= (i << SCOPE_OFF);
		u = PyInt_FromLong(flags);
		if (!u)
			return 0;
		if (PyDict_SetItem(symbols, name, u) < 0) {
			Py_DECREF(u);
			return 0;
		}
		Py_DECREF(u);
	}

        free_value = PyInt_FromLong(FREE << SCOPE_OFF);
        if (!free_value)
		return 0;

        /* add a free variable when it's only use is for creating a closure */
        pos = 0;
	while (PyDict_Next(free, &pos, &name, &v)) {
		PyObject *o = PyDict_GetItem(symbols, name);

		if (o) {
			/* It could be a free variable in a method of
			   the class that has the same name as a local
			   or global in the class scope.
			*/
			if  (classflag && 
			     PyInt_AS_LONG(o) & (DEF_BOUND | DEF_GLOBAL)) {
				long i = PyInt_AS_LONG(o) | DEF_FREE_CLASS;
				o = PyInt_FromLong(i);
				if (!o) {
					Py_DECREF(free_value);
					return 0;
				}
				if (PyDict_SetItem(symbols, name, o) < 0) {
					Py_DECREF(o);
					Py_DECREF(free_value);
					return 0;
				}
				Py_DECREF(o);
			}
			/* else it's not free, probably a cell */
			continue;
		}
		if (!PyDict_GetItem(bound, name))
			continue;       /* it's a global */

		if (PyDict_SetItem(symbols, name, free_value) < 0) {
			Py_DECREF(free_value);
			return 0;
		}
        }
        Py_DECREF(free_value);
	return 1;
}   
示例#21
0
static yajl_gen_status ProcessObject(_YajlEncoder *self, PyObject *object)
{
    yajl_gen handle = (yajl_gen)(self->_generator);
    yajl_gen_status status = yajl_gen_in_error_state;
    PyObject *iterator, *item;
    unsigned short int decref = 0;

    if (object == Py_None) {
        return yajl_gen_null(handle);
    }
    if (object == Py_True) {
        return yajl_gen_bool(handle, 1);
    }
    if (object == Py_False) {
        return yajl_gen_bool(handle, 0);
    }
    if (PyUnicode_Check(object)) {
        object = PyUnicode_AsUTF8String(object);
        decref = 1;
    }
    if (PyString_Check(object)) {
        const unsigned char *buffer = NULL;
        Py_ssize_t length;
        PyString_AsStringAndSize(object, (char **)&buffer, &length);
        status = yajl_gen_string(handle, buffer, (unsigned int)(length));
        if (decref) {
            Py_XDECREF(object);
        }
        return status;
    }
    if (PyInt_Check(object)) {
        return yajl_gen_integer(handle, PyInt_AsLong(object));
    }
    if (PyLong_Check(object)) {
        return yajl_gen_integer(handle, PyLong_AsLong(object));
    }
    if (PyFloat_Check(object)) {
        return yajl_gen_double(handle, PyFloat_AsDouble(object));
    }
    if (PyList_Check(object)) {
        /*
         * Recurse and handle the list 
         */
        iterator = PyObject_GetIter(object);
        if (iterator == NULL)
            goto exit;
        status = yajl_gen_array_open(handle);
        while ((item = PyIter_Next(iterator))) {
            status = ProcessObject(self, item);
            Py_XDECREF(item);
        }
        Py_XDECREF(iterator);
        status = yajl_gen_array_close(handle);
        return status;
    }
    if (PyDict_Check(object)) {
        PyObject *key, *value;
        Py_ssize_t position = 0;

        status = yajl_gen_map_open(handle);
        while (PyDict_Next(object, &position, &key, &value)) {
            status = ProcessObject(self, key);
            status = ProcessObject(self, value);
        }
        return yajl_gen_map_close(handle);
    }

        
    exit:
        return yajl_gen_in_error_state;
}
示例#22
0
static int
analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, 
	      PyObject *global)
{
	PyObject *name, *v, *local = NULL, *scope = NULL, *newbound = NULL;
	PyObject *newglobal = NULL, *newfree = NULL;
	int i, success = 0;
	Py_ssize_t pos = 0;

	local = PyDict_New();
	if (!local)
		goto error;
	scope = PyDict_New();
	if (!scope)
		goto error;
	newglobal = PyDict_New();
	if (!newglobal)
		goto error;
	newfree = PyDict_New();
	if (!newfree)
		goto error;
	newbound = PyDict_New();
	if (!newbound)
		goto error;

	if (ste->ste_type == ClassBlock) {
		/* make a copy of globals before calling analyze_name(),
		   because global statements in the class have no effect
		   on nested functions.
		*/
		if (PyDict_Update(newglobal, global) < 0)
			goto error;
		if (bound)
			if (PyDict_Update(newbound, bound) < 0)
				goto error;
	}

	assert(PySTEntry_Check(ste));
	assert(PyDict_Check(ste->ste_symbols));
	while (PyDict_Next(ste->ste_symbols, &pos, &name, &v)) {
		long flags = PyInt_AS_LONG(v);
		if (!analyze_name(ste, scope, name, flags, bound, local, free,
				  global))
			goto error;
	}

	if (ste->ste_type != ClassBlock) {
		if (ste->ste_type == FunctionBlock) {
			if (PyDict_Update(newbound, local) < 0)
				goto error;
		}
		if (bound) {
			if (PyDict_Update(newbound, bound) < 0)
				goto error;
		}
		if (PyDict_Update(newglobal, global) < 0)
			goto error;
	}

	/* Recursively call analyze_block() on each child block */
	for (i = 0; i < PyList_GET_SIZE(ste->ste_children); ++i) {
		PyObject *c = PyList_GET_ITEM(ste->ste_children, i);
		PySTEntryObject* entry;
		assert(c && PySTEntry_Check(c));
		entry = (PySTEntryObject*)c;
		if (!analyze_block(entry, newbound, newfree, newglobal))
			goto error;
		if (entry->ste_free || entry->ste_child_free)
			ste->ste_child_free = 1;
	}

	if (ste->ste_type == FunctionBlock && !analyze_cells(scope, newfree))
		goto error;
	if (!update_symbols(ste->ste_symbols, scope, bound, newfree,
			    ste->ste_type == ClassBlock))
		goto error;
	if (!check_unoptimized(ste))
		goto error;

	if (PyDict_Update(free, newfree) < 0)
		goto error;
	success = 1;
 error:
	Py_XDECREF(local);
	Py_XDECREF(scope);
	Py_XDECREF(newbound);
	Py_XDECREF(newglobal);
	Py_XDECREF(newfree);
	if (!success)
		assert(PyErr_Occurred());
	return success;
}
示例#23
0
/**
 *******************************************************************************************************
 * 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);
	}
}
示例#24
0
文件: amd.c 项目: ChiahungTai/cvxopt
static int set_defaults(double *control)
{
    int_t pos=0;
    int param_id;
    PyObject *param, *key, *value;
#if PY_MAJOR_VERSION < 3
    char *keystr; 
#endif
    char err_str[100];

    amd_defaults(control);

    if (!(param = PyObject_GetAttrString(amd_module, "options")) ||
        !PyDict_Check(param)){
        PyErr_SetString(PyExc_AttributeError, "missing amd.options"
            "dictionary");
        return 0;
    }
    while (PyDict_Next(param, &pos, &key, &value))
#if PY_MAJOR_VERSION >= 3
        if ((PyUnicode_Check(key)) && 
            get_param_idx(_PyUnicode_AsString(key),&param_id)) {
            if (!PyLong_Check(value) && !PyFloat_Check(value)){
                sprintf(err_str, "invalid value for AMD parameter: %-.20s",
                    _PyUnicode_AsString(key));
#else
        if ((keystr = PyString_AsString(key)) && get_param_idx(keystr,
            &param_id)) {
            if (!PyInt_Check(value) && !PyFloat_Check(value)){
                sprintf(err_str, "invalid value for AMD parameter: "
                    "%-.20s", keystr);
#endif
                PyErr_SetString(PyExc_ValueError, err_str);
                Py_DECREF(param);
                return 0;
            }
            control[param_id] = PyFloat_AsDouble(value);
        }
    Py_DECREF(param);
    return 1;
}


static char doc_order[] =
    "Computes the approximate minimum degree ordering of a square "
    "matrix.\n\n"
    "p = order(A, uplo='L')\n\n"
    "PURPOSE\n"
    "Computes a permutation p that reduces fill-in in the Cholesky\n"
    "factorization of A[p,p].\n\n"
    "ARGUMENTS\n"
    "A         square sparse matrix\n\n"
    "uplo      'L' or 'U'.  If uplo is 'L', the lower triangular part\n"
    "          of A is used and the upper triangular is ignored.  If\n"
    "          uplo is 'U', the upper triangular part is used and the\n"
    "          lower triangular part is ignored.\n\n"
    "p         'i' matrix of length equal to the order of A";


static PyObject* order_c(PyObject *self, PyObject *args, PyObject *kwrds)
{
    spmatrix *A;
    matrix *perm;
#if PY_MAJOR_VERSION >= 3
    int uplo_ = 'L';
#endif
    char uplo = 'L';
    int j, k, n, nnz, alloc=0, info;
    int_t *rowind=NULL, *colptr=NULL;
    double control[AMD_CONTROL];
    char *kwlist[] = {"A", "uplo", NULL};

#if PY_MAJOR_VERSION >= 3
    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|C", kwlist, &A,
        &uplo_)) return NULL;
    uplo = (char) uplo_;
#else
    if (!PyArg_ParseTupleAndKeywords(args, kwrds, "O|c", kwlist, &A,
        &uplo)) return NULL;
#endif
    if (!set_defaults(control)) return NULL;
    if (!SpMatrix_Check(A) || SP_NROWS(A) != SP_NCOLS(A)){
        PyErr_SetString(PyExc_TypeError, "A must be a square sparse "
            "matrix");
        return NULL;
    }
    if (uplo != 'U' && uplo != 'L') err_char("uplo", "'L', 'U'");
    if (!(perm = (matrix *) Matrix_New((int)SP_NROWS(A),1,INT)))
        return PyErr_NoMemory();
    n = SP_NROWS(A);
    for (nnz=0, j=0; j<n; j++) {
        if (uplo == 'L'){
            for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] && SP_ROW(A)[k]<j; k++);
            nnz += SP_COL(A)[j+1] - k;
        }
        else {
            for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] && SP_ROW(A)[k] <= j;
                k++);
            nnz += k - SP_COL(A)[j];
        }
    }
    if (nnz == SP_NNZ(A)){
        colptr = (int_t *) SP_COL(A);
        rowind = (int_t *) SP_ROW(A);
    }
    else {
        alloc = 1;
        colptr = (int_t *) calloc(n+1, sizeof(int_t));
        rowind = (int_t *) calloc(nnz, sizeof(int_t));
        if (!colptr || !rowind) {
            Py_XDECREF(perm);  free(colptr);  free(rowind);
            return PyErr_NoMemory();
        }
        colptr[0] = 0;
        for (j=0; j<n; j++) {
            if (uplo == 'L'){
                for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] && SP_ROW(A)[k] < j; 
                    k++);
                nnz = SP_COL(A)[j+1] - k;
                colptr[j+1] = colptr[j] + nnz;
                memcpy(rowind + colptr[j], (int_t *) SP_ROW(A) + k,
                    nnz*sizeof(int_t));
            }
            else {
                for (k=SP_COL(A)[j]; k<SP_COL(A)[j+1] && SP_ROW(A)[k] <= j;
                    k++);
                nnz = k - SP_COL(A)[j];
                colptr[j+1] = colptr[j] + nnz;
                memcpy(rowind + colptr[j], (int_t *) (SP_ROW(A) +
                    SP_COL(A)[j]), nnz*sizeof(int_t));
            }
        }
    }
    info = amd_order(n, colptr, rowind, MAT_BUFI(perm), control, NULL);
    if (alloc){
        free(colptr);
        free(rowind);
    }
    switch (info) {
        case AMD_OUT_OF_MEMORY:
            Py_XDECREF(perm);
            return PyErr_NoMemory();

        case AMD_INVALID:
            Py_XDECREF(perm);
            return Py_BuildValue("");

        case AMD_OK:
            return (PyObject *) perm;
    }
    return Py_BuildValue("");
}

static PyMethodDef amd_functions[] = {
    {"order", (PyCFunction) order_c, METH_VARARGS|METH_KEYWORDS, doc_order},
    {NULL}  /* Sentinel */
};

#if PY_MAJOR_VERSION >= 3

static PyModuleDef amd_module_def = {
    PyModuleDef_HEAD_INIT,
    "amd",
    amd__doc__,
    -1,
    amd_functions,
    NULL, NULL, NULL, NULL
};

PyMODINIT_FUNC PyInit_amd(void)
{
    if (!(amd_module = PyModule_Create(&amd_module_def))) return NULL;
    PyModule_AddObject(amd_module, "options", PyDict_New());
    if (import_cvxopt() < 0) return NULL;
    return amd_module;
}

#else
PyMODINIT_FUNC initamd(void)
{
    amd_module = Py_InitModule3("cvxopt.amd", amd_functions, amd__doc__);
    PyModule_AddObject(amd_module, "options", PyDict_New());
    if (import_cvxopt() < 0) return;
}
bool PythonScript::compile(bool for_eval)
{
	// Support for the convenient col() and cell() functions.
	// This can't be done anywhere else, because we need access to the local
	// variables self, i and j.
	if(Context->inherits("Table")) {
		// A bit of a hack, but we need either IndexError or len() from __builtins__.
		PyDict_SetItemString(localDict, "__builtins__",
				PyDict_GetItemString(env()->globalDict(), "__builtins__"));
		PyObject *ret = PyRun_String(
				"def col(c,*arg):\n"
				"\ttry: return self.cell(c,arg[0])\n"
				"\texcept(IndexError): return self.cell(c,i)\n"
				"def cell(c,r):\n"
				"\treturn self.cell(c,r)\n"
				"def tablecol(t,c):\n"
				"\treturn self.folder().rootFolder().table(t,True).cell(c,i)\n"
				"def _meth_table_col_(t,c):\n"
				"\treturn t.cell(c,i)\n"
				"self.__class__.col = _meth_table_col_",
				Py_file_input, localDict, localDict);
		if (ret)
			Py_DECREF(ret);
		else
			PyErr_Print();
	} else if(Context->inherits("Matrix")) {
		// A bit of a hack, but we need either IndexError or len() from __builtins__.
		PyDict_SetItemString(localDict, "__builtins__",
				PyDict_GetItemString(env()->globalDict(), "__builtins__"));
		PyObject *ret = PyRun_String(
				"def cell(*arg):\n"
				"\ttry: return self.cell(arg[0],arg[1])\n"
				"\texcept(IndexError): return self.cell(i,j)\n",
				Py_file_input, localDict, localDict);
		if (ret)
			Py_DECREF(ret);
		else
			PyErr_Print();
	}
	bool success=false;
	Py_XDECREF(PyCode);
	// Simplest case: Code is a single expression
	PyCode = Py_CompileString(Code, Name, Py_eval_input);

	if (PyCode)
		success = true;
	else if (for_eval) {
		// Code contains statements (or errors) and we want to get a return
		// value from it.
		// So we wrap the code into a function definition,
		// execute that (as Py_file_input) and store the function object in PyCode.
		// See http://mail.python.org/pipermail/python-list/2001-June/046940.html
		// for why there isn't an easier way to do this in Python.
		PyErr_Clear(); // silently ignore errors
		PyObject *key, *value;
#if PY_VERSION_HEX >= 0x02050000
		Py_ssize_t i=0;
#else
		int i=0;
#endif
		QString signature = "";
		while(PyDict_Next(localDict, &i, &key, &value))
			signature.append(PyString_AsString(key)).append(",");
		signature.truncate(signature.length()-1);
		QString fdef = "def __doit__("+signature+"):\n";
		fdef.append(Code);
		fdef.replace('\n',"\n\t");
		PyCode = Py_CompileString(fdef, Name, Py_file_input);
		if (PyCode){
			PyObject *tmp = PyDict_New();
			Py_XDECREF(PyEval_EvalCode((PyCodeObject*)PyCode, env()->globalDict(), tmp));
			Py_DECREF(PyCode);
			PyCode = PyDict_GetItemString(tmp,"__doit__");
			Py_XINCREF(PyCode);
			Py_DECREF(tmp);
		}
		success = (PyCode != NULL);
	} else {
		// Code contains statements (or errors), but we do not need to get
		// a return value.
		PyErr_Clear(); // silently ignore errors
		PyCode = Py_CompileString(Code, Name, Py_file_input);
		success = (PyCode != NULL);
	}

	if (!success){
		compiled = compileErr;
		emit_error(env()->errorMsg(), 0);
	} else
		compiled = isCompiled;
	return success;
}
示例#26
0
/**
Node Class methods
Returns an error code. TRUE for success, FALSE for error...
*/
static int _Node_input_sum(Node *self, PyObject *inputs, double *sum)
{
	// Iterate over the items in the weights dict

	PyObject *key, *pyweight;
	double weight, value = 0, recursive_val;
	Py_ssize_t pos = 0;
	int result = TRUE;
	*sum = 0;

	while (PyDict_Next(self->weights, &pos, &key, &pyweight)) {
		// First verify that the weight is a float
		if (!PyFloat_Check(pyweight)) {
			PyErr_Format(PyExc_ValueError, "The value of the weights dict was NOT a float!");
	 		result = FALSE;
		}
		else {
			weight = PyFloat_AS_DOUBLE(pyweight);
			// If node is a Node, call its inputsum. Else, it's an input index.
			if (PyObject_IsInstance(key, (PyObject*) self->ob_type))
			{

				if (_Node_output((Node*) key, inputs, &recursive_val))
					*sum += weight * recursive_val;
				else
					result = FALSE;
			}
			else if (PyObject_IsInstance(key, (PyObject*) &BiasNodeType))
			{
				*sum += weight * 1;
			}
			else if (PyInt_Check(key))// It's an input index
			{
				Py_ssize_t index = PyInt_AsSsize_t(key);
				// Two cases, python list or numpy list
				if (PyList_CheckExact(inputs)) // Python list
				{
					PyObject *pyval = PyList_GetItem(inputs, index);
					if (pyval == NULL)
						result = FALSE;
					else
			 			value = PyFloat_AS_DOUBLE(pyval);
				}
				else // Numpy list
				{
					double *ptr = (double *) PyArray_GETPTR1((PyArrayObject*) inputs, index);
					if (ptr == NULL)
						result = FALSE;
					else
			 			value = *ptr;
				}

				*sum += weight * value;
			}
			else // Someone f****d up the weight dict
			{
				PyErr_Format(PyExc_ValueError, "The key of the weights dict was neither a Node nor an Int!");
			 	result = FALSE;
			}
		} //if float
	} //while
	return result;
}
示例#27
0
int uwsgi_response_subhandler_pump(struct wsgi_request *wsgi_req) {

	PyObject *pychunk;
	int i;

	char sc[4];

	// ok its a yield
	if (!wsgi_req->async_placeholder) {
		if (PyDict_Check((PyObject *)wsgi_req->async_result)) {


			PyObject *status = PyDict_GetItemString((PyObject *)wsgi_req->async_result, "status");
			if (!status) {
				uwsgi_log("invalid Pump response (status code).\n"); 
				goto clear; 
			}

			PyObject *headers = PyDict_GetItemString((PyObject *)wsgi_req->async_result, "headers");
			if (!headers) {
				uwsgi_log("invalid Pump response (headers).\n"); 
				goto clear; 
			}


			wsgi_req->async_placeholder =  PyDict_GetItemString((PyObject *)wsgi_req->async_result, "body");
			if (!wsgi_req->async_placeholder) {
				uwsgi_log("invalid Pump response (body).\n"); 
				goto clear; 
			}

			// get the status code
			if (!PyInt_Check(status)) {
				uwsgi_log("invalid Pump response (status code).\n"); 
				goto clear; 
			}

			if (uwsgi_num2str2n(PyInt_AsLong(status), sc, 4) != 3) {
				uwsgi_log("invalid Pump response (status code).\n"); 
				goto clear; 
			}

			if (uwsgi_response_prepare_headers(wsgi_req, sc, 3)) {
				uwsgi_log("unable to prepare response headers\n");
			}

			PyObject *hhkey, *hhvalue;
#ifdef UWSGI_PYTHON_OLD
			int hhpos = 0;
#else
			Py_ssize_t hhpos = 0;
#endif
			while (PyDict_Next(headers, &hhpos, &hhkey, &hhvalue)) {
				if (!PyString_Check(hhkey)) continue;

				char *k = PyString_AsString(hhkey);
				size_t kl = PyString_Size(hhkey);	
				k[0] = toupper((int) k[0]);

				if (PyList_Check(hhvalue)) {
					for(i=0;i<PyList_Size(hhvalue);i++) {
						PyObject *item = PyList_GetItem(hhvalue, i);
						if (PyString_Check(item)) {
							if (uwsgi_response_add_header(wsgi_req, k, kl, PyString_AsString(item), PyString_Size(item))) goto clear;
						}
					}	
				}
				else if (PyString_Check(hhvalue)) {
					if (uwsgi_response_add_header(wsgi_req, k, kl, PyString_AsString(hhvalue), PyString_Size(hhvalue))) goto clear;
				}
			}

			Py_INCREF((PyObject *)wsgi_req->async_placeholder);

			if (PyString_Check((PyObject *)wsgi_req->async_placeholder)) {
				UWSGI_RELEASE_GIL
				uwsgi_response_write_body_do(wsgi_req, PyString_AsString(wsgi_req->async_placeholder), PyString_Size(wsgi_req->async_placeholder));
				UWSGI_GET_GIL
				uwsgi_py_check_write_errors {
                                        uwsgi_py_write_exception(wsgi_req);
                                }
                		goto clear;
        		}
#ifdef PYTHREE
			else if ((wsgi_req->sendfile_fd = PyObject_AsFileDescriptor((PyObject *)wsgi_req->async_placeholder)) > -1) {
QVariant PythonTypeConverter::toVariant(PyObject *input)
{

    if(PyBool_Check(input))
        return QVariant(input == Py_True);
    if(PyLong_Check(input))
        return QVariant((int)PyLong_AsLong(input));
    if(PyFloat_Check(input))
        return QVariant(PyFloat_AsDouble(input));

    QString strVal = toString(input);
    if(!strVal.isNull())
        return strVal;

    if(PyList_Check(input))
    {
        int len = PyList_Size(input);
        QList<QVariant> list;
        for(int i=0; i<len; i++)
            list << toVariant(PyList_GetItem(input, i));
        return bestFittingList(list);
    }
    if(PyTuple_Check(input))
    {
        int len = PyTuple_Size(input);
        QList<QVariant> list;
        for(int i=0; i<len; i++)
            list << toVariant(PyTuple_GetItem(input, i));
        return bestFittingList(list);
    }
    if(PyDict_Check(input))
    {
        QVariantMap map;
        PyObject* key = 0;
        PyObject* value = 0;
        Py_ssize_t i = 0;
        while (PyDict_Next(input, &i, &key, &value))
        {
            map.insert(toVariant(key).toString(), toVariant(value));
        }
        if(map.contains("type"))
        {
            QString type = map["type"].toString();
            if(type == "Point")
                return QPointF(map["x"].toDouble(), map["y"].toDouble());
            if(type == "Size")
                return QSizeF(map["width"].toDouble(), map["height"].toDouble());
            if(type == "Rect")
                return QRectF(map["x"].toDouble(), map["y"].toDouble(),map["width"].toDouble(), map["height"].toDouble());
            if(type == "Vector3D")
                return QVector3D(map["x"].toDouble(), map["y"].toDouble(),map["z"].toDouble());
            if(type == "Vector4D")
                return QVector4D(map["x"].toDouble(), map["y"].toDouble(),map["z"].toDouble(),map["w"].toDouble());
            if(type == "Pose2d")
                return QVariant::fromValue<Pose2d>(Pose2d(map["x"].toDouble(), map["y"].toDouble(),map["phi"].toDouble()));
        }
        return map;

    }
    return QVariant();

}
示例#29
0
/**
 *******************************************************************************************************
 * 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;
	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;
		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 {
					as_error_update(err, AEROSPIKE_ERR_PARAM, "Bin name should be of type string");
					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 (check_type(py_value, operation, err)) {
                    goto CLEANUP;
				} else if (PyString_Check(py_value) && (operation == AS_OPERATOR_INCR)) {
                    char * incr_string = PyString_AsString(py_value);
                    int incr_value = 0, sign = 1;

                    if (strlen(incr_string) > 15) {
				        as_error_update(err, AEROSPIKE_ERR_PARAM, "Unsupported string length for increment operation");
                        goto CLEANUP;
                    }
                    if (*incr_string == '-') {
                        incr_string = incr_string + 1;
                        sign = -1;
                    } else if (*incr_string == '+') {
                        incr_string = incr_string + 1;
                        sign = 1;
                    }
                    while (*incr_string != '\0') {
                        if (*incr_string >= 48 && *incr_string <= 57) {
                            incr_value = (incr_value * 10) + (*incr_string ^ 0x30);
                        } else {
				            as_error_update(err, AEROSPIKE_ERR_PARAM, "Unsupported operand type(s) for +: 'int' and 'str'");
                            goto CLEANUP;
                        }
                        incr_string = incr_string + 1;
                    }
                    incr_value = incr_value * sign;
                    py_value = PyInt_FromLong(incr_value);
                }
			} else if ((!py_value) && (operation != AS_OPERATOR_READ)) {
				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);
					} else {
						val = PyString_AsString(py_value);
					}
					as_operations_add_append_str(&ops, bin, val);
					break;
				case AS_OPERATOR_PREPEND:
					if (PyUnicode_Check(py_value)) {
						py_ustr1 = PyUnicode_AsUTF8String(py_value);
						val = PyString_AsString(py_ustr1);
					} else {
						val = PyString_AsString(py_value);
					}
					as_operations_add_prepend_str(&ops, bin, val);
					break;
				case AS_OPERATOR_INCR:
					if (PyInt_Check(py_value)) {
                        offset = PyInt_AsLong(py_value);
                    } else if ( PyLong_Check(py_value) ) {
                        offset = PyLong_AsLong(py_value);
                        if(-1 == offset) {
                            as_error_update(err, AEROSPIKE_ERR_PARAM, "integer value exceeds sys.maxsize");
                            goto CLEANUP;
                        }
                    }
                    as_operations_add_incr(&ops, bin, offset);
                    break;
				case AS_OPERATOR_TOUCH:
					if (PyInt_Check(py_value)) {
                        ops.ttl = PyInt_AsLong(py_value);
                    } else if ( 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(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:
					as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid operation given");
			}
		}
	}

	// Initialize record
	as_record_init(rec, 0);

	aerospike_key_operate(self->as, err, operate_policy_p, key, &ops, &rec);
	if (err->code != AEROSPIKE_OK) {
		as_error_update(err, err->code, NULL);
		goto CLEANUP;
	}
	if(rec) {
		record_to_pyobject(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);
	}
}
示例#30
0
文件: flow.cpp 项目: Rona111/frePPLe
PyObject* Flow::create(PyTypeObject* pytype, PyObject* args, PyObject* kwds)
{
  try
  {
    // Pick up the operation
    PyObject* oper = PyDict_GetItemString(kwds, "operation");
    if (!oper)
      throw DataException("missing operation on Flow");
    if (!PyObject_TypeCheck(oper, Operation::metadata->pythonClass))
      throw DataException("flow operation must be of type operation");

    // Pick up the buffer
    PyObject* buf = PyDict_GetItemString(kwds, "buffer");
    if (!buf)
      throw DataException("missing buffer on Flow");
    if (!PyObject_TypeCheck(buf, Buffer::metadata->pythonClass))
      throw DataException("flow buffer must be of type buffer");

    // Pick up the quantity
    PyObject* q1 = PyDict_GetItemString(kwds, "quantity");
    double q2 = q1 ? PythonData(q1).getDouble() : 1.0;

    // Pick up the effectivity dates
    DateRange eff;
    PyObject* eff_start = PyDict_GetItemString(kwds, "effective_start");
    if (eff_start)
    {
      PythonData d(eff_start);
      eff.setStart(d.getDate());
    }
    PyObject* eff_end = PyDict_GetItemString(kwds, "effective_end");
    if (eff_end)
    {
      PythonData d(eff_end);
      eff.setEnd(d.getDate());
    }

    // Pick up the type and create the flow
    Flow *l;
    PyObject* t = PyDict_GetItemString(kwds, "type");
    if (t)
    {
      PythonData d(t);
      if (d.getString() == "flow_end")
        l = new FlowEnd(
          static_cast<Operation*>(oper),
          static_cast<Buffer*>(buf),
          q2
        );
      else if (d.getString() == "flow_fixed_end")
        l = new FlowFixedEnd(
          static_cast<Operation*>(oper),
          static_cast<Buffer*>(buf),
          q2
        );
      else if (d.getString() == "flow_fixed_start")
        l = new FlowFixedStart(
          static_cast<Operation*>(oper),
          static_cast<Buffer*>(buf),
          q2
        );
      else
        l = new FlowStart(
          static_cast<Operation*>(oper),
          static_cast<Buffer*>(buf),
          q2
        );
    }
    else
      l = new FlowStart(
        static_cast<Operation*>(oper),
        static_cast<Buffer*>(buf),
        q2
      );

    // Iterate over extra keywords, and set attributes.   @todo move this responsibility to the readers...
    if (l)
    {
      l->setEffective(eff);
      PyObject *key, *value;
      Py_ssize_t pos = 0;
      while (PyDict_Next(kwds, &pos, &key, &value))
      {
        PythonData field(value);
        PyObject* key_utf8 = PyUnicode_AsUTF8String(key);
        DataKeyword attr(PyBytes_AsString(key_utf8));
        Py_DECREF(key_utf8);
        if (!attr.isA(Tags::effective_end) && !attr.isA(Tags::effective_start)
          && !attr.isA(Tags::operation) && !attr.isA(Tags::buffer)
          && !attr.isA(Tags::quantity) && !attr.isA(Tags::type)
          && !attr.isA(Tags::action))
        {
          const MetaFieldBase* fmeta = l->getType().findField(attr.getHash());
          if (!fmeta && l->getType().category)
            fmeta = l->getType().category->findField(attr.getHash());
          if (fmeta)
            // Update the attribute
            fmeta->setField(l, field);
          else
            PyErr_Format(PyExc_AttributeError,
                "attribute '%S' on '%s' can't be updated",
                key, Py_TYPE(l)->tp_name);
        }
      };
    }

    // Return the object
    Py_INCREF(l);
    return static_cast<PyObject*>(l);
  }
  catch (...)
  {
    PythonType::evalException();
    return NULL;
  }
}