Пример #1
0
/*	Set new unique item at `i` index in LDAPValueList to `newitem`. Case-insensitive,
	the `newitem` is also appended to the added list, or remove from the deleted list.
	Same goes for the replaced item.
*/
int
LDAPValueList_SetItem(LDAPValueList *self, Py_ssize_t i, PyObject *newitem) {
	int rc = -1;
	PyObject *olditem;

	if (UniqueList_SetItem((UniqueList *)self, i, newitem) != 0) return -1;

	olditem = PyList_GetItem((PyObject *)self, i);
	if (olditem == NULL) return -1;
	rc = UniqueList_Remove_wFlg(self->added, olditem);
	if (rc == -1) return -1;
	if (rc == 0) {
		if (UniqueList_Append(self->deleted, olditem) == -1) {
			PyErr_BadInternalCall();
			return -1;
		}
	}

	rc = UniqueList_Remove_wFlg(self->deleted, newitem);
	if (rc == -1) return -1;
	if (rc == 0) {
		if (UniqueList_Append(self->added, newitem) == -1) {
			PyErr_BadInternalCall();
			return -1;
		}
	}
	return 0;
}
Пример #2
0
static int
UL_ass_item(UniqueList *self, Py_ssize_t i, PyObject *v) {
    if (i < 0 || i >= Py_SIZE(self)) {
        PyErr_SetString(PyExc_IndexError,
                        "list assignment index out of range");
        return -1;
    }
    if (v == NULL) return UniqueList_SetSlice(self, i, i+1, v);
    return UniqueList_SetItem(self, i, v);
}
Пример #3
0
/*	This function is based on list_ass_subscript from Python source listobject.c.
	But it uses UniqueList's setslice and setitem functions instead of memory opertation.
	It is probably a much more slower, but cleaner (easier) solution.
*/
static int
UL_ass_subscript(UniqueList *self, PyObject *item, PyObject *value) {
    size_t cur;
	Py_ssize_t i;
	Py_ssize_t start, stop, step, slicelength;
    PyObject *seq;
    PyObject **seqitems;

	if (PyIndex_Check(item)) {
		i = PyNumber_AsSsize_t(item, PyExc_IndexError);
		if (i == -1 && PyErr_Occurred()) return -1;
		if (i < 0) i += PyList_GET_SIZE(self);
		return UL_ass_item(self, i, value);
    } else if (PySlice_Check(item)) {
    	if (PySlice_GetIndicesEx(item, Py_SIZE(self), &start, &stop, &step, &slicelength) < 0) {
    		return -1;
    	}

    	if (step == 1) return UniqueList_SetSlice(self, start, stop, value);

        /* Make sure s[5:2] = [..] inserts at the right place:
           before 5, not before 2. */
    	if ((step < 0 && start < stop) || (step > 0 && start > stop)) {
    		stop = start;
    	}

    	if (value == NULL) {
    		/* delete slice */
            if (slicelength <= 0) return 0;

            if (step < 0) {
                stop = start + 1;
                start = stop + step*(slicelength - 1) - 1;
                step = -step;
            }

            for (cur = start, i = 0; cur < (size_t)stop; cur += step, i++) {
            	if (UniqueList_SetSlice(self, cur-i, cur+1-i, (PyObject *)NULL) != 0) {
            		return -1;
            	}
            }
            return 0;
        } else {
        	/* assign slice */
        	/* protect against a[::-1] = a */
        	if (self == (UniqueList *)value) {
        		seq = PyList_GetSlice(value, 0, PyList_GET_SIZE(value));
        	} else {
        		seq = PySequence_Fast(value, "must assign iterable to extended slice");
        	}
        	if (!seq) return -1;

        	if (PySequence_Fast_GET_SIZE(seq) != slicelength) {
        		PyErr_Format(PyExc_ValueError, "attempt to assign sequence of size %zd to extended slice of "
        				"size %zd", PySequence_Fast_GET_SIZE(seq), slicelength);
        		Py_DECREF(seq);
        		return -1;
        	}

        	if (!slicelength) {
        		Py_DECREF(seq);
        		return 0;
        	}

        	seqitems = PySequence_Fast_ITEMS(seq);
        	for (cur = start, i = 0; i < slicelength; cur += (size_t)step, i++) {
        		if (UniqueList_SetItem(self, cur, seqitems[i]) != 0) {
        			return -1;
        		}
        	}
        	Py_DECREF(seq);
        	return 0;
        }
    } else {
    	PyErr_Format(PyExc_TypeError, "list indices must be integers, not %.200s", item->ob_type->tp_name);
    	return -1;
    }
}