1/*
2 * Manual wrappers for CFBitVector
3 */
4#include <Python.h>
5#include "pyobjc-api.h"
6
7#import <CoreFoundation/CoreFoundation.h>
8
9
10static PyObject*
11mod_CFBitVectorCreate(PyObject* self __attribute__((__unused__)),
12	PyObject* args)
13{
14	PyObject* py_allocator;
15	PyObject* py_bytes;
16	Py_ssize_t count;
17	CFAllocatorRef allocator;
18	CFBitVectorRef vector;
19
20
21	if (!PyArg_ParseTuple(args, "OO" Py_ARG_SIZE_T, &py_allocator, &py_bytes, &count)) {
22		return NULL;
23	}
24
25	if (PyObjC_PythonToObjC(@encode(CFAllocatorRef), py_allocator, &allocator) < 0) {
26		return NULL;
27	}
28
29	PyObject* buf;
30	void* bytes;
31	int r;
32	Py_ssize_t byteCount;
33
34	if (count == -1) {
35		byteCount = -1;
36	} else {
37		byteCount = count / 8;
38	}
39
40        r = PyObjC_PythonToCArray(NO, NO, "z", py_bytes, &bytes, &byteCount, &buf);
41	if (r == -1) {
42		return NULL;
43	}
44
45	if (count == -1) {
46		count = byteCount * 8;
47	}
48
49	vector = CFBitVectorCreate(allocator, bytes, count);
50
51	PyObjC_FreeCArray(r, bytes);
52	Py_XDECREF(buf);
53
54	PyObject* result = PyObjC_ObjCToPython(@encode(CFBitVectorRef), &vector);
55	if (vector) {
56		CFRelease(vector);
57	}
58	return result;
59}
60
61static PyObject*
62mod_CFBitVectorGetBits(PyObject* self __attribute__((__unused__)),
63		PyObject* args)
64{
65	PyObject* py_vector;
66	PyObject* py_range;
67	PyObject* py_bytes;
68	CFBitVectorRef vector;
69	CFRange range;
70
71	if (!PyArg_ParseTuple(args, "OOO", &py_vector, &py_range, &py_bytes)) {
72		return NULL;
73	}
74
75
76	if (PyObjC_PythonToObjC(@encode(CFBitVectorRef), py_vector, &vector) < 0) {
77		return NULL;
78	}
79	if (PyObjC_PythonToObjC(@encode(CFRange), py_range, &range) < 0) {
80		return NULL;
81	}
82	if (py_bytes != Py_None) {
83		PyErr_Format(PyExc_ValueError, "argument 3: expecting None, got instance of %s",
84			py_bytes->ob_type->tp_name);
85		return NULL;
86	}
87
88	PyObject* buffer = PyString_FromStringAndSize(NULL, (range.length+7)/8);
89	if (buffer == NULL) {
90		return NULL;
91	}
92	memset(PyString_AsString(buffer), 0, (range.length+7)/8);
93
94	CFBitVectorGetBits(vector, range, (unsigned char*)PyString_AsString(buffer));
95	return buffer;
96}
97
98
99
100
101
102static PyMethodDef mod_methods[] = {
103        {
104		"CFBitVectorCreate",
105		(PyCFunction)mod_CFBitVectorCreate,
106		METH_VARARGS,
107		NULL
108	},
109        {
110		"CFBitVectorGetBits",
111		(PyCFunction)mod_CFBitVectorGetBits,
112		METH_VARARGS,
113		NULL
114	},
115	{ 0, 0, 0, 0 } /* sentinel */
116};
117
118void init_CFBitVector(void);
119void init_CFBitVector(void)
120{
121	PyObject* m = Py_InitModule4("_CFBitVector", mod_methods, "", NULL,
122		PYTHON_API_VERSION);
123
124	PyObjC_ImportAPI(m);
125}
126