blob: f221395eac24e007ace5384e93f0128ad0f2877e [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)
Guido van Rossume06b6b82006-04-23 07:43:54 +0000133 return -1;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000134 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);
Guido van Rossume06b6b82006-04-23 07:43:54 +0000154 Py_DECREF(item);
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000155 if (value == -1 && PyErr_Occurred())
156 goto error;
157
158 /* Range check */
159 if (value < 0 || value >= 256) {
160 PyErr_SetString(PyExc_ValueError, "bytes must be in range(0, 256)");
161 goto error;
162 }
163
164 /* Append the byte */
165 /* XXX Speed this up */
166 if (PyBytes_Resize((PyObject *)self, self->ob_size+1) < 0)
167 goto error;
168 self->ob_sval[self->ob_size-1] = value;
169 }
170
171 /* Clean up and return success */
172 Py_DECREF(it);
173 return 0;
174
175 error:
176 /* Error handling when it != NULL */
177 Py_DECREF(it);
178 return -1;
179}
180
181static PyObject *
182bytes_repr(PyBytesObject *self)
183{
184 PyObject *list;
185 PyObject *str;
186 PyObject *result;
187 int err;
188 int i;
189
190 if (self->ob_size == 0)
191 return PyString_FromString("bytes()");
192
193 list = PyList_New(0);
194 if (list == NULL)
195 return NULL;
196
197 str = PyString_FromString("bytes([");
198 if (str == NULL)
199 goto error;
200
201 err = PyList_Append(list, str);
202 Py_DECREF(str);
203 if (err < 0)
204 goto error;
205
206 for (i = 0; i < self->ob_size; i++) {
207 char buffer[20];
208 sprintf(buffer, ", 0x%02x", (unsigned char) (self->ob_sval[i]));
209 str = PyString_FromString((i == 0) ? buffer+2 : buffer);
210 if (str == NULL)
211 goto error;
212 err = PyList_Append(list, str);
213 Py_DECREF(str);
214 if (err < 0)
215 goto error;
216 }
217
218 str = PyString_FromString("])");
219 if (str == NULL)
220 goto error;
221
222 err = PyList_Append(list, str);
223 Py_DECREF(str);
224 if (err < 0)
225 goto error;
226
227 str = PyString_FromString("");
228 if (str == NULL)
229 goto error;
230
231 result = _PyString_Join(str, list);
232 Py_DECREF(str);
233 Py_DECREF(list);
234 return result;
235
236 error:
237 /* Error handling when list != NULL */
238 Py_DECREF(list);
239 return NULL;
240}
241
242static PyObject *
243bytes_richcompare(PyBytesObject *self, PyBytesObject *other, int op)
244{
245 PyObject *res;
246 int minsize;
247 int cmp;
248
249 if (!PyBytes_Check(self) || !PyBytes_Check(other)) {
250 Py_INCREF(Py_NotImplemented);
251 return Py_NotImplemented;
252 }
253
254 if (self->ob_size != other->ob_size && (op == Py_EQ || op == Py_NE)) {
255 /* Shortcut: if the lengths differ, the objects differ */
256 cmp = (op == Py_NE);
257 }
258 else {
259 minsize = self->ob_size;
260 if (other->ob_size < minsize)
261 minsize = other->ob_size;
262
263 cmp = memcmp(self->ob_sval, other->ob_sval, minsize);
264 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
265
266 if (cmp == 0) {
267 if (self->ob_size < other->ob_size)
268 cmp = -1;
269 else if (self->ob_size > other->ob_size)
270 cmp = 1;
271 }
272
273 switch (op) {
274 case Py_LT: cmp = cmp < 0; break;
275 case Py_LE: cmp = cmp <= 0; break;
276 case Py_EQ: cmp = cmp == 0; break;
277 case Py_NE: cmp = cmp != 0; break;
278 case Py_GT: cmp = cmp > 0; break;
279 case Py_GE: cmp = cmp >= 0; break;
280 }
281 }
282
283 res = cmp ? Py_True : Py_False;
284 Py_INCREF(res);
285 return res;
286}
287
288static void
289bytes_dealloc(PyBytesObject *self)
290{
291 if (self->ob_sval != 0) {
292 PyMem_Free(self->ob_sval);
293 }
294 self->ob_type->tp_free((PyObject *)self);
295}
296
297static PySequenceMethods bytes_as_sequence = {
298 (lenfunc)bytes_length, /*sq_length*/
299 (binaryfunc)0, /*sq_concat*/
300 (ssizeargfunc)0, /*sq_repeat*/
301 (ssizeargfunc)bytes_getitem, /*sq_item*/
302 (ssizessizeargfunc)0, /*sq_slice*/
303 0, /*sq_ass_item*/
304 0, /*sq_ass_slice*/
305 (objobjproc)0, /*sq_contains*/
306};
307
308static PyMappingMethods bytes_as_mapping = {
309 (lenfunc)bytes_length,
310 (binaryfunc)0,
311 0,
312};
313
314static PyBufferProcs bytes_as_buffer = {
315/*
316 (readbufferproc)bytes_buffer_getreadbuf,
317 (writebufferproc)bytes_buffer_getwritebuf,
318 (segcountproc)bytes_buffer_getsegcount,
319 (charbufferproc)bytes_buffer_getcharbuf,
320*/
321};
322
323static PyMethodDef
324bytes_methods[] = {
325 {NULL, NULL}
326};
327
328PyDoc_STRVAR(bytes_doc,
329"bytes([iterable]) -> new array of bytes.\n\
330\n\
331If an argument is given it must be an iterable yielding ints in range(256).");
332
333PyTypeObject PyBytes_Type = {
334 PyObject_HEAD_INIT(&PyType_Type)
335 0,
336 "bytes",
337 sizeof(PyBytesObject),
338 0,
339 (destructor)bytes_dealloc, /* tp_dealloc */
340 0, /* tp_print */
341 0, /* tp_getattr */
342 0, /* tp_setattr */
343 0, /* tp_compare */
344 (reprfunc)bytes_repr, /* tp_repr */
345 0, /* tp_as_number */
346 &bytes_as_sequence, /* tp_as_sequence */
347 &bytes_as_mapping, /* tp_as_mapping */
348 bytes_nohash, /* tp_hash */
349 0, /* tp_call */
350 0, /* tp_str */
351 PyObject_GenericGetAttr, /* tp_getattro */
352 0, /* tp_setattro */
353 &bytes_as_buffer, /* tp_as_buffer */
354 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags */ /* bytes is 'final' or 'sealed' */
355 bytes_doc, /* tp_doc */
356 0, /* tp_traverse */
357 0, /* tp_clear */
358 (richcmpfunc)bytes_richcompare, /* tp_richcompare */
359 0, /* tp_weaklistoffset */
360 0, /* tp_iter */
361 0, /* tp_iternext */
362 bytes_methods, /* tp_methods */
363 0, /* tp_members */
364 0, /* tp_getset */
365 0, /* tp_base */
366 0, /* tp_dict */
367 0, /* tp_descr_get */
368 0, /* tp_descr_set */
369 0, /* tp_dictoffset */
370 (initproc)bytes_init, /* tp_init */
371 PyType_GenericAlloc, /* tp_alloc */
372 PyType_GenericNew, /* tp_new */
373 PyObject_Del, /* tp_free */
374};