Files
controller-wisetopdataserver/python/biopro/ext/channel.h
T
2021-12-20 14:52:55 +08:00

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_