-
Notifications
You must be signed in to change notification settings - Fork 6
/
streql.c
57 lines (47 loc) · 1.54 KB
/
streql.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <Python.h>
// The core function: test two regions of memory for bytewise equality.
static int equals_internal(const char *x, unsigned int xlen, const char *y, unsigned int ylen) {
if (xlen != ylen) return 0;
int i, result = 0;
for (i = 0; i < xlen; i++) result |= x[i] ^ y[i];
return result == 0;
}
static PyObject *equals(PyObject *self, PyObject *args) {
const char *x = NULL, *y = NULL; unsigned int xlen, ylen;
if (!PyArg_ParseTuple(args, "et#et#", "utf8", &x, &xlen, "utf8", &y, &ylen)) return NULL;
int equal = equals_internal(x, xlen, y, ylen);
PyMem_Free((void*)x); PyMem_Free((void*)y);
if (equal) {
Py_RETURN_TRUE;
} else {
Py_RETURN_FALSE;
}
}
static PyMethodDef streql_methods[] = {
{"equals", (PyCFunction)equals, METH_VARARGS,
"equals(x, y): does x == y?\nRuntime does not depend on the bytes in the strings."},
{NULL, NULL}
};
// The rest of this is rather ugly boilerplate to allow this module to compile on both
// Python 2 and 3. For more details, see http://docs.python.org/3/howto/cporting.html
#if PY_MAJOR_VERSION >= 3
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT, "streql", NULL, 0, streql_methods, NULL, NULL, NULL, NULL
};
#define INITERROR return NULL
PyObject *PyInit_streql(void)
#else
#define INITERROR return
void initstreql(void)
#endif
{
#if PY_MAJOR_VERSION >= 3
PyObject *module = PyModule_Create(&moduledef);
#else
PyObject *module = Py_InitModule("streql", streql_methods);
#endif
if (module == NULL) INITERROR;
#if PY_MAJOR_VERSION >= 3
return module;
#endif
}