1 /*
2 * Python UUID module that wraps libuuid -
3 * DCE compatible Universally Unique Identifier library.
4 */
5
6 #define PY_SSIZE_T_CLEAN
7
8 #include "Python.h"
9 #ifdef HAVE_UUID_UUID_H
10 #include <uuid/uuid.h>
11 #elif defined(HAVE_UUID_H)
12 #include <uuid.h>
13 #endif
14
15 static PyObject *
py_uuid_generate_time_safe(PyObject * Py_UNUSED (context),PyObject * Py_UNUSED (ignored))16 py_uuid_generate_time_safe(PyObject *Py_UNUSED(context),
17 PyObject *Py_UNUSED(ignored))
18 {
19 uuid_t uuid;
20 #ifdef HAVE_UUID_GENERATE_TIME_SAFE
21 int res;
22
23 res = uuid_generate_time_safe(uuid);
24 return Py_BuildValue("y#i", (const char *) uuid, sizeof(uuid), res);
25 #elif defined(HAVE_UUID_CREATE)
26 uint32_t status;
27 uuid_create(&uuid, &status);
28 # if defined(HAVE_UUID_ENC_BE)
29 unsigned char buf[sizeof(uuid)];
30 uuid_enc_be(buf, &uuid);
31 return Py_BuildValue("y#i", buf, sizeof(uuid), (int) status);
32 # else
33 return Py_BuildValue("y#i", (const char *) &uuid, sizeof(uuid), (int) status);
34 # endif
35 #else
36 uuid_generate_time(uuid);
37 return Py_BuildValue("y#O", (const char *) uuid, sizeof(uuid), Py_None);
38 #endif
39 }
40
41
42 static PyMethodDef uuid_methods[] = {
43 {"generate_time_safe", py_uuid_generate_time_safe, METH_NOARGS, NULL},
44 {NULL, NULL, 0, NULL} /* sentinel */
45 };
46
47 static struct PyModuleDef uuidmodule = {
48 PyModuleDef_HEAD_INIT,
49 .m_name = "_uuid",
50 .m_size = -1,
51 .m_methods = uuid_methods,
52 };
53
54 PyMODINIT_FUNC
PyInit__uuid(void)55 PyInit__uuid(void)
56 {
57 PyObject *mod;
58 assert(sizeof(uuid_t) == 16);
59 #ifdef HAVE_UUID_GENERATE_TIME_SAFE
60 int has_uuid_generate_time_safe = 1;
61 #else
62 int has_uuid_generate_time_safe = 0;
63 #endif
64 mod = PyModule_Create(&uuidmodule);
65 if (mod == NULL) {
66 return NULL;
67 }
68 if (PyModule_AddIntConstant(mod, "has_uuid_generate_time_safe",
69 has_uuid_generate_time_safe) < 0) {
70 Py_DECREF(mod);
71 return NULL;
72 }
73
74 return mod;
75 }
76