_dbus_bindings: debug-impl.h -> debug.c
[dbus-python-phuang.git] / _dbus_bindings / bytes-impl.h
blob62b45711fe4ae064e0c37cc5a4ec3fc2f4e2ba78
1 /* D-Bus Byte and ByteArray types.
3 * Copyright (C) 2006 Collabora Ltd.
5 * Licensed under the Academic Free License version 2.1
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 static PyTypeObject ByteType, ByteArrayType;
27 static inline int Byte_Check(PyObject *o)
29 return (o->ob_type == &ByteType)
30 || PyObject_IsInstance(o, (PyObject *)&ByteType);
33 static inline int ByteArray_Check(PyObject *o)
35 return (o->ob_type == &ByteArrayType)
36 || PyObject_IsInstance(o, (PyObject *)&ByteArrayType);
39 PyDoc_STRVAR(Byte_tp_doc,
40 "Byte(integer or str of length 1[, variant_level])\n"
41 "\n"
42 "Byte is a subtype of int, with range restricted to [0, 255].\n"
43 "\n"
44 "A Byte b may be converted to a str of length 1 via str(b) == chr(b).\n"
47 static PyObject *
48 Byte_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
50 PyObject *obj;
51 PyObject *tuple;
52 long variantness = 0;
53 static char *argnames[] = {"variant_level", NULL};
55 if (PyTuple_Size(args) > 1) {
56 PyErr_SetString(PyExc_TypeError, "Byte constructor takes no more "
57 "than one positional argument");
58 return NULL;
60 if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwargs,
61 "|l:__new__", argnames,
62 &variantness)) return NULL;
63 if (variantness < 0) {
64 PyErr_SetString(PyExc_ValueError,
65 "variant_level must be non-negative");
66 return NULL;
69 /* obj is only a borrowed ref for the moment */
70 obj = PyTuple_GetItem(args, 0);
72 if (PyString_Check(obj)) {
73 /* string of length 1, we hope */
74 if (PyString_GET_SIZE(obj) != 1) {
75 goto bad_arg;
77 obj = PyInt_FromLong((unsigned char)(PyString_AS_STRING(obj)[0]));
79 else if (PyInt_Check(obj)) {
80 long i = PyInt_AS_LONG(obj);
82 if (obj->ob_type == cls &&
83 ((DBusPythonInt *)obj)->variant_level == variantness) {
84 Py_INCREF(obj);
85 return obj;
87 if (i < 0 || i > 255) goto bad_range;
88 /* else make it a new reference */
89 Py_INCREF(obj);
91 else {
92 goto bad_arg;
95 tuple = Py_BuildValue("(O)", obj);
96 if (!tuple) return NULL;
97 Py_DECREF(obj);
98 obj = NULL;
100 obj = DBusPythonIntType.tp_new(cls, tuple, kwargs);
101 Py_DECREF(tuple);
102 tuple = NULL;
103 return obj;
105 bad_arg:
106 PyErr_SetString(PyExc_TypeError, "Expected a string of length 1, "
107 "or an int in the range 0-255");
108 return NULL;
109 bad_range:
110 PyErr_SetString(PyExc_ValueError, "Integer outside range 0-255");
111 return NULL;
114 static PyObject *
115 Byte_tp_str(PyObject *self)
117 unsigned char str[2] = { (unsigned char)PyInt_AS_LONG(self), 0 };
118 return PyString_FromStringAndSize((char *)str, 1);
121 static PyTypeObject ByteType = {
122 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
124 "dbus.Byte",
127 0, /* tp_dealloc */
128 0, /* tp_print */
129 0, /* tp_getattr */
130 0, /* tp_setattr */
131 0, /* tp_compare */
132 DBusPythonInt_tp_repr, /* tp_repr */
133 0, /* tp_as_number */
134 0, /* tp_as_sequence */
135 0, /* tp_as_mapping */
136 0, /* tp_hash */
137 0, /* tp_call */
138 Byte_tp_str, /* tp_str */
139 0, /* tp_getattro */
140 0, /* tp_setattro */
141 0, /* tp_as_buffer */
142 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
143 Byte_tp_doc, /* tp_doc */
144 0, /* tp_traverse */
145 0, /* tp_clear */
146 0, /* tp_richcompare */
147 0, /* tp_weaklistoffset */
148 0, /* tp_iter */
149 0, /* tp_iternext */
150 0, /* tp_methods */
151 0, /* tp_members */
152 0, /* tp_getset */
153 DEFERRED_ADDRESS(&PyInt_Type), /* tp_base */
154 0, /* tp_dict */
155 0, /* tp_descr_get */
156 0, /* tp_descr_set */
157 0, /* tp_dictoffset */
158 0, /* tp_init */
159 0, /* tp_alloc */
160 Byte_new, /* tp_new */
163 PyDoc_STRVAR(ByteArray_tp_doc,
164 "ByteArray(str)\n"
165 "\n"
166 "ByteArray is a subtype of str which can be used when you want an\n"
167 "efficient immutable representation of a D-Bus byte array (signature 'ay').\n"
168 "\n"
169 "The subscript operation byte_array[i] returns Byte instances. Otherwise,\n"
170 "it's just a string.\n"
173 static PyObject *
174 ByteArray_sq_item (PyObject *self, int i)
176 unsigned char c;
177 PyObject *args;
179 if (i < 0 || i >= PyString_GET_SIZE(self)) {
180 PyErr_SetString(PyExc_IndexError, "ByteArray index out of range");
181 return NULL;
183 c = ((unsigned char *)PyString_AS_STRING(self))[i];
184 args = Py_BuildValue("(l)", (long)c);
185 if (!args)
186 return NULL;
187 return PyObject_Call((PyObject *)&ByteType, args, NULL);
190 static PyObject *
191 ByteArray_mp_subscript(PyObject *self, PyObject *other)
193 long i;
194 if (PyInt_Check(other)) {
195 i = PyInt_AS_LONG(other);
196 if (i < 0) i += PyString_GET_SIZE (self);
197 return ByteArray_sq_item(self, i);
199 else if (PyLong_Check(other)) {
200 i = PyLong_AsLong(other);
201 if (i == -1 && PyErr_Occurred()) return NULL;
202 if (i < 0) i += PyString_GET_SIZE(self);
203 return ByteArray_sq_item(self, i);
205 else {
206 /* slices just return strings */
207 return (PyString_Type.tp_as_mapping->mp_subscript)(self, other);
211 static PyMappingMethods ByteArray_tp_as_mapping = {
212 0, /* mp_length */
213 ByteArray_mp_subscript, /* mp_subscript */
214 0, /* mp_ass_subscript */
217 static PySequenceMethods ByteArray_tp_as_sequence = {
218 0, /* sq_length */
219 0, /* sq_concat */
220 0, /* sq_repeat */
221 ByteArray_sq_item, /* sq_item */
222 0, /* sq_slice */
223 0, /* sq_ass_item */
224 0, /* sq_ass_slice */
225 0, /* sq_contains */
228 static PyTypeObject ByteArrayType = {
229 PyObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type))
231 "dbus.ByteArray",
234 0, /* tp_dealloc */
235 0, /* tp_print */
236 0, /* tp_getattr */
237 0, /* tp_setattr */
238 0, /* tp_compare */
239 0, /* tp_repr */
240 0, /* tp_as_number */
241 &ByteArray_tp_as_sequence, /* tp_as_sequence */
242 &ByteArray_tp_as_mapping, /* tp_as_mapping */
243 0, /* tp_hash */
244 0, /* tp_call */
245 0, /* tp_str */
246 0, /* tp_getattro */
247 0, /* tp_setattro */
248 0, /* tp_as_buffer */
249 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
250 ByteArray_tp_doc, /* tp_doc */
251 0, /* tp_traverse */
252 0, /* tp_clear */
253 0, /* tp_richcompare */
254 0, /* tp_weaklistoffset */
255 0, /* tp_iter */
256 0, /* tp_iternext */
257 0, /* tp_methods */
258 0, /* tp_members */
259 0, /* tp_getset */
260 DEFERRED_ADDRESS(&DBusPythonStringType), /* tp_base */
261 0, /* tp_dict */
262 0, /* tp_descr_get */
263 0, /* tp_descr_set */
264 0, /* tp_dictoffset */
265 0, /* tp_init */
266 0, /* tp_alloc */
267 0, /* tp_new */
270 static inline int
271 init_byte_types(void)
273 ByteType.tp_base = &DBusPythonIntType;
274 if (PyType_Ready(&ByteType) < 0) return 0;
275 ByteType.tp_print = NULL;
277 ByteArrayType.tp_base = &DBusPythonStringType;
278 if (PyType_Ready(&ByteArrayType) < 0) return 0;
279 ByteArrayType.tp_print = NULL;
281 return 1;
284 static inline int
285 insert_byte_types(PyObject *this_module)
287 Py_INCREF(&ByteType);
288 if (PyModule_AddObject(this_module, "Byte",
289 (PyObject *)&ByteType) < 0) return 0;
290 Py_INCREF(&ByteArrayType);
291 if (PyModule_AddObject(this_module, "ByteArray",
292 (PyObject *)&ByteArrayType) < 0) return 0;
294 return 1;
297 /* vim:set ft=c cino< sw=4 sts=4 et: */