207 lines
4.0 KiB
C
207 lines
4.0 KiB
C
#include "Python.h"
|
|
|
|
#ifndef _BPS_CHANNEL_H_
|
|
#define _BPS_CHANNEL_H_
|
|
|
|
typedef struct {
|
|
unsigned int capacity;
|
|
unsigned int size;
|
|
unsigned int* storage;
|
|
} IntSet;
|
|
|
|
void int_set_init(IntSet* mask) {
|
|
if (mask == NULL) return;
|
|
|
|
mask->capacity = 0;
|
|
mask->size = 0;
|
|
mask->storage = NULL;
|
|
}
|
|
|
|
IntSet* int_set_new() {
|
|
IntSet* mask = (IntSet*)PyMem_Malloc(sizeof(IntSet));
|
|
|
|
int_set_init(mask);
|
|
|
|
return mask;
|
|
}
|
|
|
|
void int_set_free(IntSet* mask) {
|
|
if (mask == NULL) return;
|
|
|
|
if (mask->storage != NULL) {
|
|
PyMem_Free(mask->storage);
|
|
mask->storage = NULL;
|
|
}
|
|
PyMem_Free(mask);
|
|
}
|
|
|
|
void int_set_clear(IntSet* mask) {
|
|
if (mask == NULL) return;
|
|
|
|
if (mask->storage != NULL) {
|
|
PyMem_Free(mask->storage);
|
|
mask->storage = NULL;
|
|
}
|
|
|
|
mask->capacity = 0;
|
|
mask->size = 0;
|
|
}
|
|
|
|
int int_set_indexof(IntSet* mask, unsigned int value) {
|
|
if (mask == NULL) {
|
|
PyErr_SetString(PyExc_RuntimeError, "NULL");
|
|
return -1;
|
|
}
|
|
|
|
unsigned int* ch = mask->storage;
|
|
|
|
for (unsigned int i = 0; i < mask->size; i++) {
|
|
if (*ch == value) return i;
|
|
ch++;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int int_set_contain(IntSet* mask, unsigned int value) {
|
|
if (mask == NULL) {
|
|
PyErr_SetString(PyExc_RuntimeError, "NULL");
|
|
return 0;
|
|
}
|
|
|
|
unsigned int* ch = mask->storage;
|
|
|
|
for (unsigned int i = 0; i < mask->size; i++) {
|
|
if (*ch == value) return 1;
|
|
ch++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int int_set_extend(IntSet* mask) {
|
|
if (mask == NULL) {
|
|
PyErr_SetString(PyExc_RuntimeError, "NULL");
|
|
return 0;
|
|
}
|
|
|
|
unsigned int old_cap = mask->capacity;
|
|
|
|
unsigned int new_cap = old_cap + 4;
|
|
|
|
unsigned int* new_ch = (unsigned int*)PyMem_Realloc(mask->storage, new_cap * sizeof(unsigned int));
|
|
|
|
if (new_ch == NULL) {
|
|
PyErr_SetString(PyExc_ValueError, "PyMem_Malloc fail");
|
|
return 0;
|
|
}
|
|
|
|
mask->storage = new_ch;
|
|
mask->capacity = new_cap;
|
|
|
|
return 1;
|
|
}
|
|
|
|
int int_set_add(IntSet* mask, unsigned int value) {
|
|
if (mask == NULL) {
|
|
PyErr_SetString(PyExc_RuntimeError, "NULL");
|
|
return 0;
|
|
}
|
|
|
|
unsigned int* ch = mask->storage;
|
|
|
|
for (unsigned int i = 0; i < mask->size; i++, ch++) {
|
|
if (*ch == value) return 0;
|
|
}
|
|
|
|
if (mask->size == mask->capacity) {
|
|
if (!int_set_extend(mask)) return 0;
|
|
|
|
ch = mask->storage + mask->size;
|
|
}
|
|
|
|
*ch = value;
|
|
mask->size++;
|
|
|
|
return 1;
|
|
}
|
|
|
|
int int_set_add_list(IntSet* mask, PyObject* channel) {
|
|
PyObject* iterator = PyObject_GetIter(channel);
|
|
|
|
if (iterator == NULL) return 0;
|
|
|
|
PyObject* item;
|
|
int add = 1;
|
|
|
|
while ((item = PyIter_Next(iterator)) != NULL) {
|
|
long value = PyLong_AsLong(item);
|
|
Py_DECREF(item);
|
|
|
|
if (value >= 0) {
|
|
if (int_set_add(mask, value)) {
|
|
add = 1;
|
|
}
|
|
}
|
|
|
|
if (PyErr_Occurred()) break;
|
|
}
|
|
|
|
Py_DECREF(iterator);
|
|
|
|
return PyErr_Occurred() ? 0 : add;
|
|
}
|
|
|
|
int int_set_del(IntSet* mask, unsigned int value) {
|
|
if (mask == NULL) {
|
|
PyErr_SetString(PyExc_RuntimeError, "NULL");
|
|
return 0;
|
|
}
|
|
|
|
if (mask->size == 0) return 0;
|
|
|
|
unsigned int i = 0;
|
|
|
|
for (unsigned int* ch = mask->storage; i < mask->size; i++, ch++) {
|
|
if (*ch == value) break;
|
|
}
|
|
|
|
if (i == mask->size) {
|
|
// no value contain
|
|
return 0;
|
|
}
|
|
|
|
if (i < mask->size - 1) {
|
|
// not at last place
|
|
for (unsigned int* ch = mask->storage + i; i < mask->size; i++, ch++) {
|
|
*ch = *(ch + 1);
|
|
}
|
|
}
|
|
|
|
mask->size--;
|
|
|
|
return 1;
|
|
}
|
|
|
|
PyObject *int_set_list(IntSet *mask) {
|
|
PyObject *list = PyList_New(mask->size);
|
|
|
|
if (list == NULL) return NULL;
|
|
|
|
for (unsigned int i = 0; i < mask->size; i++) {
|
|
PyObject *value = PyLong_FromLong(mask->storage[i]);
|
|
if (value == NULL) goto int_set_list_error;
|
|
|
|
PyList_SET_ITEM(list, i, value);
|
|
}
|
|
|
|
return list;
|
|
|
|
int_set_list_error:
|
|
Py_DECREF(list);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
#endif // _BPS_CHANNEL_H_
|