int PySlice_GetIndicesEx(PyObject *_r, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength) { if (PySlice_Unpack(_r, start, stop, step) < 0) return -1; *slicelength = PySlice_AdjustIndices(length, start, stop, *step); return 0; }
static PyObject * mmap_subscript(mmap_object *self, PyObject *item) { CHECK_VALID(NULL); if (PyIndex_Check(item)) { Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) return NULL; if (i < 0) i += self->size; if (i < 0 || i >= self->size) { PyErr_SetString(PyExc_IndexError, "mmap index out of range"); return NULL; } return PyLong_FromLong(Py_CHARMASK(self->data[i])); } else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelen; if (PySlice_Unpack(item, &start, &stop, &step) < 0) { return NULL; } slicelen = PySlice_AdjustIndices(self->size, &start, &stop, step); if (slicelen <= 0) return PyBytes_FromStringAndSize("", 0); else if (step == 1) return PyBytes_FromStringAndSize(self->data + start, slicelen); else { char *result_buf = (char *)PyMem_Malloc(slicelen); Py_ssize_t cur, i; PyObject *result; if (result_buf == NULL) return PyErr_NoMemory(); for (cur = start, i = 0; i < slicelen; cur += step, i++) { result_buf[i] = self->data[cur]; } result = PyBytes_FromStringAndSize(result_buf, slicelen); PyMem_Free(result_buf); return result; } } else { PyErr_SetString(PyExc_TypeError, "mmap indices must be integers"); return NULL; } }
static int mmap_ass_subscript(mmap_object *self, PyObject *item, PyObject *value) { CHECK_VALID(-1); if (!is_writable(self)) return -1; if (PyIndex_Check(item)) { Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); Py_ssize_t v; if (i == -1 && PyErr_Occurred()) return -1; if (i < 0) i += self->size; if (i < 0 || i >= self->size) { PyErr_SetString(PyExc_IndexError, "mmap index out of range"); return -1; } if (value == NULL) { PyErr_SetString(PyExc_TypeError, "mmap doesn't support item deletion"); return -1; } if (!PyIndex_Check(value)) { PyErr_SetString(PyExc_TypeError, "mmap item value must be an int"); return -1; } v = PyNumber_AsSsize_t(value, PyExc_TypeError); if (v == -1 && PyErr_Occurred()) return -1; if (v < 0 || v > 255) { PyErr_SetString(PyExc_ValueError, "mmap item value must be " "in range(0, 256)"); return -1; } self->data[i] = (char) v; return 0; } else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelen; Py_buffer vbuf; if (PySlice_Unpack(item, &start, &stop, &step) < 0) { return -1; } slicelen = PySlice_AdjustIndices(self->size, &start, &stop, step); if (value == NULL) { PyErr_SetString(PyExc_TypeError, "mmap object doesn't support slice deletion"); return -1; } if (PyObject_GetBuffer(value, &vbuf, PyBUF_SIMPLE) < 0) return -1; if (vbuf.len != slicelen) { PyErr_SetString(PyExc_IndexError, "mmap slice assignment is wrong size"); PyBuffer_Release(&vbuf); return -1; } if (slicelen == 0) { } else if (step == 1) { memcpy(self->data + start, vbuf.buf, slicelen); } else { Py_ssize_t cur, i; for (cur = start, i = 0; i < slicelen; cur += step, i++) { self->data[cur] = ((char *)vbuf.buf)[i]; } } PyBuffer_Release(&vbuf); return 0; } else { PyErr_SetString(PyExc_TypeError, "mmap indices must be integer"); return -1; } }