blob: 8fc089bf540b1648e322923a5a6298f6374bff4c [file] [log] [blame]
Guido van Rossum4dfe8a12006-04-22 23:28:04 +00001/* Bytes object implementation */
2
3/* XXX TO DO: optimizations */
4
5#define PY_SSIZE_T_CLEAN
6#include "Python.h"
7
8/* Direct API functions */
9
10PyObject *
11PyBytes_FromStringAndSize(const char *sval, Py_ssize_t size)
12{
13 PyBytesObject *new;
14
15 if (size != 0) {
16 assert(sval != NULL);
17 assert(size > 0);
18 }
19
20 new = PyObject_New(PyBytesObject, &PyBytes_Type);
21 if (new == NULL)
22 return NULL;
23
24 if (size > 0) {
25 new->ob_sval = PyMem_Malloc(size);
26 if (new->ob_sval == NULL) {
27 Py_DECREF(new);
28 return NULL;
29 }
30 memcpy(new->ob_sval, sval, size);
31 new->ob_size = size;
32 }
33
34 return (PyObject *)new;
35}
36
37Py_ssize_t
38PyBytes_Size(PyObject *self)
39{
40 assert(self != NULL);
41 assert(PyBytes_Check(self));
42
43 return ((PyBytesObject *)self)->ob_size;
44}
45
46char *
47PyBytes_AsString(PyObject *self)
48{
49 assert(self != NULL);
50 assert(PyBytes_Check(self));
51
52 return ((PyBytesObject *)self)->ob_sval;
53}
54
55int
56PyBytes_Resize(PyObject *self, Py_ssize_t size)
57{
58 void *sval;
59
60 assert(self != NULL);
61 assert(PyBytes_Check(self));
62 assert(size >= 0);
63
64 sval = PyMem_Realloc(((PyBytesObject *)self)->ob_sval, size);
65 if (sval == NULL) {
66 PyErr_NoMemory();
67 return -1;
68 }
69
70 ((PyBytesObject *)self)->ob_sval = sval;
71 ((PyBytesObject *)self)->ob_size = size;
72
73 return 0;
74}
75
76/* Functions stuffed into the type object */
77
78static Py_ssize_t
79bytes_length(PyBytesObject *self)
80{
81 return self->ob_size;
82}
83
84static PyObject *
85bytes_getitem(PyBytesObject *self, Py_ssize_t i)
86{
87 if (i < 0)
88 i += self->ob_size;
89 if (i < 0 || i >= self->ob_size) {
90 PyErr_SetString(PyExc_IndexError, "bytes index out of range");
91 return NULL;
92 }
93 return PyInt_FromLong((unsigned char)(self->ob_sval[i]));
94}
95
96static long
97bytes_nohash(PyObject *self)
98{
99 PyErr_SetString(PyExc_TypeError, "bytes objects are unhashable");
100 return -1;
101}
102
103static int
104bytes_init(PyBytesObject *self, PyObject *args, PyObject *kwds)
105{
106 static char *kwlist[] = {"sequence", 0};
107 PyObject *arg = NULL;
108 PyObject *it; /* iter(arg) */
109 PyObject *(*iternext)(PyObject *);
110
111 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:bytes", kwlist, &arg))
112 return -1;
113
114 /* Verify list invariants established by PyType_GenericAlloc() */
115 if (self->ob_size != 0) {
116 assert(self->ob_sval != NULL);
117 assert(self->ob_size > 0);
118 }
119
120 /* Empty previous contents */
121 if (PyBytes_Resize((PyObject *)self, 0) < 0)
122 return -1;
123
124 /* Quick check if we're done */
125 if (arg == 0)
126 return 0;
127
128 /* XXX Optimize this if the arguments is a list, tuple, or bytes */
129
130 /* Get the iterator */
131 it = PyObject_GetIter(arg);
132 if (it == NULL)
133 return 0;
134 iternext = *it->ob_type->tp_iternext;
135
136 /* Run the iterator to exhaustion */
137 for (;;) {
138 PyObject *item;
139 Py_ssize_t value;
140
141 /* Get the next item */
142 item = iternext(it);
143 if (item == NULL) {
144 if (PyErr_Occurred()) {
145 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
146 goto error;
147 PyErr_Clear();
148 }
149 break;
150 }
151
152 /* Interpret it as an int (__index__) */
153 value = PyNumber_Index(item);
154 if (value == -1 && PyErr_Occurred())
155 goto error;
156
157 /* Range check */
158 if (value < 0 || value >= 256) {
159 PyErr_SetString(PyExc_ValueError, "bytes must be in range(0, 256)");
160 goto error;
161 }
162
163 /* Append the byte */
164 /* XXX Speed this up */
165 if (PyBytes_Resize((PyObject *)self, self->ob_size+1) < 0)
166 goto error;
167 self->ob_sval[self->ob_size-1] = value;
168 }
169
170 /* Clean up and return success */
171 Py_DECREF(it);
172 return 0;
173
174 error:
175 /* Error handling when it != NULL */
176 Py_DECREF(it);
177 return -1;
178}
179
180static PyObject *
181bytes_repr(PyBytesObject *self)
182{
183 PyObject *list;
184 PyObject *str;
185 PyObject *result;
186 int err;
187 int i;
188
189 if (self->ob_size == 0)
190 return PyString_FromString("bytes()");
191
192 list = PyList_New(0);
193 if (list == NULL)
194 return NULL;
195
196 str = PyString_FromString("bytes([");
197 if (str == NULL)
198 goto error;
199
200 err = PyList_Append(list, str);
201 Py_DECREF(str);
202 if (err < 0)
203 goto error;
204
205 for (i = 0; i < self->ob_size; i++) {
206 char buffer[20];
207 sprintf(buffer, ", 0x%02x", (unsigned char) (self->ob_sval[i]));
208 str = PyString_FromString((i == 0) ? buffer+2 : buffer);
209 if (str == NULL)
210 goto error;
211 err = PyList_Append(list, str);
212 Py_DECREF(str);
213 if (err < 0)
214 goto error;
215 }
216
217 str = PyString_FromString("])");
218 if (str == NULL)
219 goto error;
220
221 err = PyList_Append(list, str);
222 Py_DECREF(str);
223 if (err < 0)
224 goto error;
225
226 str = PyString_FromString("");
227 if (str == NULL)
228 goto error;
229
230 result = _PyString_Join(str, list);
231 Py_DECREF(str);
232 Py_DECREF(list);
233 return result;
234
235 error:
236 /* Error handling when list != NULL */
237 Py_DECREF(list);
238 return NULL;
239}
240
241static PyObject *
242bytes_richcompare(PyBytesObject *self, PyBytesObject *other, int op)
243{
244 PyObject *res;
245 int minsize;
246 int cmp;
247
248 if (!PyBytes_Check(self) || !PyBytes_Check(other)) {
249 Py_INCREF(Py_NotImplemented);
250 return Py_NotImplemented;
251 }
252
253 if (self->ob_size != other->ob_size && (op == Py_EQ || op == Py_NE)) {
254 /* Shortcut: if the lengths differ, the objects differ */
255 cmp = (op == Py_NE);
256 }
257 else {
258 minsize = self->ob_size;
259 if (other->ob_size < minsize)
260 minsize = other->ob_size;
261
262 cmp = memcmp(self->ob_sval, other->ob_sval, minsize);
263 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
264
265 if (cmp == 0) {
266 if (self->ob_size < other->ob_size)
267 cmp = -1;
268 else if (self->ob_size > other->ob_size)
269 cmp = 1;
270 }
271
272 switch (op) {
273 case Py_LT: cmp = cmp < 0; break;
274 case Py_LE: cmp = cmp <= 0; break;
275 case Py_EQ: cmp = cmp == 0; break;
276 case Py_NE: cmp = cmp != 0; break;
277 case Py_GT: cmp = cmp > 0; break;
278 case Py_GE: cmp = cmp >= 0; break;
279 }
280 }
281
282 res = cmp ? Py_True : Py_False;
283 Py_INCREF(res);
284 return res;
285}
286
287static void
288bytes_dealloc(PyBytesObject *self)
289{
290 if (self->ob_sval != 0) {
291 PyMem_Free(self->ob_sval);
292 }
293 self->ob_type->tp_free((PyObject *)self);
294}
295
296static PySequenceMethods bytes_as_sequence = {
297 (lenfunc)bytes_length, /*sq_length*/
298 (binaryfunc)0, /*sq_concat*/
299 (ssizeargfunc)0, /*sq_repeat*/
300 (ssizeargfunc)bytes_getitem, /*sq_item*/
301 (ssizessizeargfunc)0, /*sq_slice*/
302 0, /*sq_ass_item*/
303 0, /*sq_ass_slice*/
304 (objobjproc)0, /*sq_contains*/
305};
306
307static PyMappingMethods bytes_as_mapping = {
308 (lenfunc)bytes_length,
309 (binaryfunc)0,
310 0,
311};
312
313static PyBufferProcs bytes_as_buffer = {
314/*
315 (readbufferproc)bytes_buffer_getreadbuf,
316 (writebufferproc)bytes_buffer_getwritebuf,
317 (segcountproc)bytes_buffer_getsegcount,
318 (charbufferproc)bytes_buffer_getcharbuf,
319*/
320};
321
322static PyMethodDef
323bytes_methods[] = {
324 {NULL, NULL}
325};
326
327PyDoc_STRVAR(bytes_doc,
328"bytes([iterable]) -> new array of bytes.\n\
329\n\
330If an argument is given it must be an iterable yielding ints in range(256).");
331
332PyTypeObject PyBytes_Type = {
333 PyObject_HEAD_INIT(&PyType_Type)
334 0,
335 "bytes",
336 sizeof(PyBytesObject),
337 0,
338 (destructor)bytes_dealloc, /* tp_dealloc */
339 0, /* tp_print */
340 0, /* tp_getattr */
341 0, /* tp_setattr */
342 0, /* tp_compare */
343 (reprfunc)bytes_repr, /* tp_repr */
344 0, /* tp_as_number */
345 &bytes_as_sequence, /* tp_as_sequence */
346 &bytes_as_mapping, /* tp_as_mapping */
347 bytes_nohash, /* tp_hash */
348 0, /* tp_call */
349 0, /* tp_str */
350 PyObject_GenericGetAttr, /* tp_getattro */
351 0, /* tp_setattro */
352 &bytes_as_buffer, /* tp_as_buffer */
353 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */ /* bytes is 'final' or 'sealed' */
354 bytes_doc, /* tp_doc */
355 0, /* tp_traverse */
356 0, /* tp_clear */
357 (richcmpfunc)bytes_richcompare, /* tp_richcompare */
358 0, /* tp_weaklistoffset */
359 0, /* tp_iter */
360 0, /* tp_iternext */
361 bytes_methods, /* tp_methods */
362 0, /* tp_members */
363 0, /* tp_getset */
364 0, /* tp_base */
365 0, /* tp_dict */
366 0, /* tp_descr_get */
367 0, /* tp_descr_set */
368 0, /* tp_dictoffset */
369 (initproc)bytes_init, /* tp_init */
370 PyType_GenericAlloc, /* tp_alloc */
371 PyType_GenericNew, /* tp_new */
372 PyObject_Del, /* tp_free */
373};