blob: 2ee71bbafbb6d3c75f0e79bee9e94e2129241750 [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"
Guido van Rossuma0867f72006-05-05 04:34:18 +00007#include "structmember.h"
Guido van Rossum4dfe8a12006-04-22 23:28:04 +00008
9/* Direct API functions */
10
11PyObject *
Guido van Rossumd624f182006-04-24 13:47:05 +000012PyBytes_FromObject(PyObject *input)
13{
14 return PyObject_CallFunctionObjArgs((PyObject *)&PyBytes_Type,
15 input, NULL);
16}
17
18PyObject *
19PyBytes_FromStringAndSize(const char *bytes, Py_ssize_t size)
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000020{
21 PyBytesObject *new;
22
Guido van Rossumd624f182006-04-24 13:47:05 +000023 assert(size >= 0);
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000024
25 new = PyObject_New(PyBytesObject, &PyBytes_Type);
26 if (new == NULL)
Guido van Rossumd624f182006-04-24 13:47:05 +000027 return NULL;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000028
Guido van Rossumd624f182006-04-24 13:47:05 +000029 if (size == 0)
30 new->ob_bytes = NULL;
31 else {
32 new->ob_bytes = PyMem_Malloc(size);
33 if (new->ob_bytes == NULL) {
34 Py_DECREF(new);
35 return NULL;
36 }
37 if (bytes != NULL)
38 memcpy(new->ob_bytes, bytes, size);
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000039 }
Guido van Rossuma0867f72006-05-05 04:34:18 +000040 new->ob_size = new->ob_alloc = size;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000041
42 return (PyObject *)new;
43}
44
45Py_ssize_t
46PyBytes_Size(PyObject *self)
47{
48 assert(self != NULL);
49 assert(PyBytes_Check(self));
50
Guido van Rossum20188312006-05-05 15:15:40 +000051 return PyBytes_GET_SIZE(self);
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000052}
53
54char *
55PyBytes_AsString(PyObject *self)
56{
57 assert(self != NULL);
58 assert(PyBytes_Check(self));
59
Guido van Rossum20188312006-05-05 15:15:40 +000060 return PyBytes_AS_STRING(self);
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000061}
62
63int
64PyBytes_Resize(PyObject *self, Py_ssize_t size)
65{
66 void *sval;
Guido van Rossuma0867f72006-05-05 04:34:18 +000067 Py_ssize_t alloc = ((PyBytesObject *)self)->ob_alloc;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000068
69 assert(self != NULL);
70 assert(PyBytes_Check(self));
71 assert(size >= 0);
72
Guido van Rossuma0867f72006-05-05 04:34:18 +000073 if (size < alloc / 2) {
74 /* Major downsize; resize down to exact size */
75 alloc = size;
76 }
77 else if (size <= alloc) {
78 /* Within allocated size; quick exit */
79 ((PyBytesObject *)self)->ob_size = size;
80 return 0;
81 }
82 else if (size <= alloc * 1.125) {
83 /* Moderate upsize; overallocate similar to list_resize() */
84 alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
85 }
86 else {
87 /* Major upsize; resize up to exact size */
88 alloc = size;
89 }
90
91 sval = PyMem_Realloc(((PyBytesObject *)self)->ob_bytes, alloc);
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000092 if (sval == NULL) {
Guido van Rossumd624f182006-04-24 13:47:05 +000093 PyErr_NoMemory();
94 return -1;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000095 }
96
Guido van Rossumd624f182006-04-24 13:47:05 +000097 ((PyBytesObject *)self)->ob_bytes = sval;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +000098 ((PyBytesObject *)self)->ob_size = size;
Guido van Rossuma0867f72006-05-05 04:34:18 +000099 ((PyBytesObject *)self)->ob_alloc = alloc;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000100
101 return 0;
102}
103
104/* Functions stuffed into the type object */
105
106static Py_ssize_t
107bytes_length(PyBytesObject *self)
108{
109 return self->ob_size;
110}
111
112static PyObject *
Guido van Rossumd624f182006-04-24 13:47:05 +0000113bytes_concat(PyBytesObject *self, PyObject *other)
114{
115 PyBytesObject *result;
116 Py_ssize_t mysize;
117 Py_ssize_t size;
118
119 if (!PyBytes_Check(other)) {
120 PyErr_Format(PyExc_TypeError,
121 "can't concat bytes to %.100s", other->ob_type->tp_name);
122 return NULL;
123 }
124
125 mysize = self->ob_size;
126 size = mysize + ((PyBytesObject *)other)->ob_size;
127 if (size < 0)
128 return PyErr_NoMemory();
129 result = (PyBytesObject *) PyBytes_FromStringAndSize(NULL, size);
130 if (result != NULL) {
131 memcpy(result->ob_bytes, self->ob_bytes, self->ob_size);
132 memcpy(result->ob_bytes + self->ob_size,
133 ((PyBytesObject *)other)->ob_bytes,
134 ((PyBytesObject *)other)->ob_size);
135 }
136 return (PyObject *)result;
137}
138
139static PyObject *
Guido van Rossum13e57212006-04-27 22:54:26 +0000140bytes_iconcat(PyBytesObject *self, PyObject *other)
141{
142 Py_ssize_t mysize;
143 Py_ssize_t osize;
144 Py_ssize_t size;
145
146 if (!PyBytes_Check(other)) {
147 PyErr_Format(PyExc_TypeError,
148 "can't concat bytes to %.100s", other->ob_type->tp_name);
149 return NULL;
150 }
151
152 mysize = self->ob_size;
153 osize = ((PyBytesObject *)other)->ob_size;
154 size = mysize + osize;
155 if (size < 0)
156 return PyErr_NoMemory();
Guido van Rossuma0867f72006-05-05 04:34:18 +0000157 if (size <= self->ob_alloc)
158 self->ob_size = size;
159 else if (PyBytes_Resize((PyObject *)self, size) < 0)
Guido van Rossum13e57212006-04-27 22:54:26 +0000160 return NULL;
161 memcpy(self->ob_bytes + mysize, ((PyBytesObject *)other)->ob_bytes, osize);
162 Py_INCREF(self);
163 return (PyObject *)self;
164}
165
166static PyObject *
Guido van Rossumd624f182006-04-24 13:47:05 +0000167bytes_repeat(PyBytesObject *self, Py_ssize_t count)
168{
169 PyBytesObject *result;
170 Py_ssize_t mysize;
171 Py_ssize_t size;
172
173 if (count < 0)
174 count = 0;
175 mysize = self->ob_size;
176 size = mysize * count;
177 if (count != 0 && size / count != mysize)
178 return PyErr_NoMemory();
179 result = (PyBytesObject *)PyBytes_FromStringAndSize(NULL, size);
180 if (result != NULL && size != 0) {
181 if (mysize == 1)
182 memset(result->ob_bytes, self->ob_bytes[0], size);
183 else {
Guido van Rossum13e57212006-04-27 22:54:26 +0000184 Py_ssize_t i;
Guido van Rossumd624f182006-04-24 13:47:05 +0000185 for (i = 0; i < count; i++)
186 memcpy(result->ob_bytes + i*mysize, self->ob_bytes, mysize);
187 }
188 }
189 return (PyObject *)result;
190}
191
192static PyObject *
Guido van Rossum13e57212006-04-27 22:54:26 +0000193bytes_irepeat(PyBytesObject *self, Py_ssize_t count)
194{
195 Py_ssize_t mysize;
196 Py_ssize_t size;
197
198 if (count < 0)
199 count = 0;
200 mysize = self->ob_size;
201 size = mysize * count;
202 if (count != 0 && size / count != mysize)
203 return PyErr_NoMemory();
Guido van Rossuma0867f72006-05-05 04:34:18 +0000204 if (size <= self->ob_alloc)
205 self->ob_size = size;
206 else if (PyBytes_Resize((PyObject *)self, size) < 0)
Guido van Rossum13e57212006-04-27 22:54:26 +0000207 return NULL;
208
209 if (mysize == 1)
210 memset(self->ob_bytes, self->ob_bytes[0], size);
211 else {
212 Py_ssize_t i;
213 for (i = 1; i < count; i++)
214 memcpy(self->ob_bytes + i*mysize, self->ob_bytes, mysize);
215 }
216
217 Py_INCREF(self);
218 return (PyObject *)self;
219}
220
221static int
222bytes_substring(PyBytesObject *self, PyBytesObject *other)
223{
224 Py_ssize_t i;
225
226 if (other->ob_size == 1) {
227 return memchr(self->ob_bytes, other->ob_bytes[0],
228 self->ob_size) != NULL;
229 }
230 if (other->ob_size == 0)
231 return 1; /* Edge case */
232 for (i = 0; i + other->ob_size <= self->ob_size; i++) {
233 /* XXX Yeah, yeah, lots of optimizations possible... */
234 if (memcmp(self->ob_bytes + i, other->ob_bytes, other->ob_size) == 0)
235 return 1;
236 }
237 return 0;
238}
239
240static int
241bytes_contains(PyBytesObject *self, PyObject *value)
242{
243 Py_ssize_t ival;
244
245 if (PyBytes_Check(value))
246 return bytes_substring(self, (PyBytesObject *)value);
247
248 ival = PyNumber_Index(value);
249 if (ival == -1 && PyErr_Occurred())
250 return -1;
251
252 if (ival < 0 || ival >= 256) {
253 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
254 return -1;
255 }
256
257 return memchr(self->ob_bytes, ival, self->ob_size) != NULL;
258}
259
260static PyObject *
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000261bytes_getitem(PyBytesObject *self, Py_ssize_t i)
262{
263 if (i < 0)
Guido van Rossumd624f182006-04-24 13:47:05 +0000264 i += self->ob_size;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000265 if (i < 0 || i >= self->ob_size) {
Guido van Rossumd624f182006-04-24 13:47:05 +0000266 PyErr_SetString(PyExc_IndexError, "bytes index out of range");
267 return NULL;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000268 }
Guido van Rossumd624f182006-04-24 13:47:05 +0000269 return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
270}
271
272static PyObject *
273bytes_getslice(PyBytesObject *self, Py_ssize_t lo, Py_ssize_t hi)
274{
275 if (lo < 0)
276 lo = 0;
277 if (hi > self->ob_size)
278 hi = self->ob_size;
279 if (lo >= hi)
280 lo = hi = 0;
281 return PyBytes_FromStringAndSize(self->ob_bytes + lo, hi - lo);
282}
283
284static int
285bytes_setslice(PyBytesObject *self, Py_ssize_t lo, Py_ssize_t hi,
286 PyObject *values)
287{
288 int avail;
289 int needed;
290 char *bytes;
291
292 if (values == NULL) {
293 bytes = NULL;
294 needed = 0;
295 }
296 else if (values == (PyObject *)self || !PyBytes_Check(values)) {
297 /* Make a copy an call this function recursively */
298 int err;
299 values = PyBytes_FromObject(values);
300 if (values == NULL)
301 return -1;
302 err = bytes_setslice(self, lo, hi, values);
303 Py_DECREF(values);
304 return err;
305 }
306 else {
307 assert(PyBytes_Check(values));
308 bytes = ((PyBytesObject *)values)->ob_bytes;
309 needed = ((PyBytesObject *)values)->ob_size;
310 }
311
312 if (lo < 0)
313 lo = 0;
314 if (hi > self->ob_size)
315 hi = self->ob_size;
316
317 avail = hi - lo;
318 if (avail < 0)
319 lo = hi = avail = 0;
320
321 if (avail != needed) {
322 if (avail > needed) {
323 /*
324 0 lo hi old_size
325 | |<----avail----->|<-----tomove------>|
326 | |<-needed->|<-----tomove------>|
327 0 lo new_hi new_size
328 */
329 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
330 self->ob_size - hi);
331 }
332 if (PyBytes_Resize((PyObject *)self,
333 self->ob_size + needed - avail) < 0)
334 return -1;
335 if (avail < needed) {
336 /*
337 0 lo hi old_size
338 | |<-avail->|<-----tomove------>|
339 | |<----needed---->|<-----tomove------>|
340 0 lo new_hi new_size
341 */
342 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
343 self->ob_size - lo - needed);
344 }
345 }
346
347 if (needed > 0)
348 memcpy(self->ob_bytes + lo, bytes, needed);
349
350 return 0;
351}
352
353static int
354bytes_setitem(PyBytesObject *self, Py_ssize_t i, PyObject *value)
355{
356 Py_ssize_t ival;
357
358 if (i < 0)
359 i += self->ob_size;
360
361 if (i < 0 || i >= self->ob_size) {
362 PyErr_SetString(PyExc_IndexError, "bytes index out of range");
363 return -1;
364 }
365
366 if (value == NULL)
367 return bytes_setslice(self, i, i+1, NULL);
368
369 ival = PyNumber_Index(value);
370 if (ival == -1 && PyErr_Occurred())
371 return -1;
372
373 if (ival < 0 || ival >= 256) {
374 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
375 return -1;
376 }
377
378 self->ob_bytes[i] = ival;
379 return 0;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000380}
381
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000382static int
383bytes_init(PyBytesObject *self, PyObject *args, PyObject *kwds)
384{
Guido van Rossumd624f182006-04-24 13:47:05 +0000385 static char *kwlist[] = {"source", "encoding", "errors", 0};
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000386 PyObject *arg = NULL;
Guido van Rossumd624f182006-04-24 13:47:05 +0000387 const char *encoding = NULL;
388 const char *errors = NULL;
389 Py_ssize_t count;
390 PyObject *it;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000391 PyObject *(*iternext)(PyObject *);
392
Guido van Rossuma0867f72006-05-05 04:34:18 +0000393 if (self->ob_size != 0) {
394 /* Empty previous contents (yes, do this first of all!) */
395 if (PyBytes_Resize((PyObject *)self, 0) < 0)
396 return -1;
397 }
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000398
Guido van Rossumd624f182006-04-24 13:47:05 +0000399 /* Parse arguments */
400 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytes", kwlist,
401 &arg, &encoding, &errors))
402 return -1;
403
404 /* Make a quick exit if no first argument */
405 if (arg == NULL) {
406 if (encoding != NULL || errors != NULL) {
407 PyErr_SetString(PyExc_TypeError,
408 "encoding or errors without sequence argument");
409 return -1;
410 }
411 return 0;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000412 }
413
Guido van Rossumd624f182006-04-24 13:47:05 +0000414 if (PyUnicode_Check(arg)) {
415 /* Encode via the codec registry */
416 PyObject *encoded;
417 char *bytes;
418 Py_ssize_t size;
419 if (encoding == NULL)
420 encoding = PyUnicode_GetDefaultEncoding();
421 encoded = PyCodec_Encode(arg, encoding, errors);
422 if (encoded == NULL)
423 return -1;
424 if (!PyString_Check(encoded)) {
425 PyErr_Format(PyExc_TypeError,
426 "encoder did not return a string object (type=%.400s)",
427 encoded->ob_type->tp_name);
428 Py_DECREF(encoded);
429 return -1;
430 }
431 bytes = PyString_AS_STRING(encoded);
432 size = PyString_GET_SIZE(encoded);
Guido van Rossuma0867f72006-05-05 04:34:18 +0000433 if (size <= self->ob_alloc)
434 self->ob_size = size;
435 else if (PyBytes_Resize((PyObject *)self, size) < 0) {
Guido van Rossumd624f182006-04-24 13:47:05 +0000436 Py_DECREF(encoded);
437 return -1;
438 }
439 memcpy(self->ob_bytes, bytes, size);
440 Py_DECREF(encoded);
441 return 0;
442 }
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000443
Guido van Rossumd624f182006-04-24 13:47:05 +0000444 /* If it's not unicode, there can't be encoding or errors */
445 if (encoding != NULL || errors != NULL) {
446 PyErr_SetString(PyExc_TypeError,
447 "encoding or errors without a string argument");
448 return -1;
449 }
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000450
Guido van Rossumd624f182006-04-24 13:47:05 +0000451 /* Is it an int? */
452 count = PyNumber_Index(arg);
453 if (count == -1 && PyErr_Occurred())
454 PyErr_Clear();
455 else {
456 if (count < 0) {
457 PyErr_SetString(PyExc_ValueError, "negative count");
458 return -1;
459 }
460 if (count > 0) {
461 if (PyBytes_Resize((PyObject *)self, count))
462 return -1;
463 memset(self->ob_bytes, 0, count);
464 }
465 return 0;
466 }
467
468 if (PyObject_CheckReadBuffer(arg)) {
469 const void *bytes;
470 Py_ssize_t size;
471 if (PyObject_AsReadBuffer(arg, &bytes, &size) < 0)
472 return -1;
473 if (PyBytes_Resize((PyObject *)self, size) < 0)
474 return -1;
475 memcpy(self->ob_bytes, bytes, size);
476 return 0;
477 }
478
479 /* XXX Optimize this if the arguments is a list, tuple */
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000480
481 /* Get the iterator */
482 it = PyObject_GetIter(arg);
483 if (it == NULL)
Guido van Rossumd624f182006-04-24 13:47:05 +0000484 return -1;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000485 iternext = *it->ob_type->tp_iternext;
486
487 /* Run the iterator to exhaustion */
488 for (;;) {
Guido van Rossumd624f182006-04-24 13:47:05 +0000489 PyObject *item;
490 Py_ssize_t value;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000491
Guido van Rossumd624f182006-04-24 13:47:05 +0000492 /* Get the next item */
493 item = iternext(it);
494 if (item == NULL) {
495 if (PyErr_Occurred()) {
496 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
497 goto error;
498 PyErr_Clear();
499 }
500 break;
501 }
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000502
Guido van Rossumd624f182006-04-24 13:47:05 +0000503 /* Interpret it as an int (__index__) */
504 value = PyNumber_Index(item);
505 Py_DECREF(item);
506 if (value == -1 && PyErr_Occurred())
507 goto error;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000508
Guido van Rossumd624f182006-04-24 13:47:05 +0000509 /* Range check */
510 if (value < 0 || value >= 256) {
511 PyErr_SetString(PyExc_ValueError,
512 "bytes must be in range(0, 256)");
513 goto error;
514 }
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000515
Guido van Rossumd624f182006-04-24 13:47:05 +0000516 /* Append the byte */
Guido van Rossuma0867f72006-05-05 04:34:18 +0000517 if (self->ob_size < self->ob_alloc)
518 self->ob_size++;
519 else if (PyBytes_Resize((PyObject *)self, self->ob_size+1) < 0)
Guido van Rossumd624f182006-04-24 13:47:05 +0000520 goto error;
521 self->ob_bytes[self->ob_size-1] = value;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000522 }
523
524 /* Clean up and return success */
525 Py_DECREF(it);
526 return 0;
527
528 error:
529 /* Error handling when it != NULL */
530 Py_DECREF(it);
531 return -1;
532}
533
534static PyObject *
535bytes_repr(PyBytesObject *self)
536{
537 PyObject *list;
538 PyObject *str;
539 PyObject *result;
540 int err;
541 int i;
542
543 if (self->ob_size == 0)
Guido van Rossumd624f182006-04-24 13:47:05 +0000544 return PyString_FromString("bytes()");
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000545
546 list = PyList_New(0);
547 if (list == NULL)
Guido van Rossumd624f182006-04-24 13:47:05 +0000548 return NULL;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000549
550 str = PyString_FromString("bytes([");
551 if (str == NULL)
Guido van Rossumd624f182006-04-24 13:47:05 +0000552 goto error;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000553
554 err = PyList_Append(list, str);
555 Py_DECREF(str);
556 if (err < 0)
Guido van Rossumd624f182006-04-24 13:47:05 +0000557 goto error;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000558
559 for (i = 0; i < self->ob_size; i++) {
Guido van Rossumd624f182006-04-24 13:47:05 +0000560 char buffer[20];
561 sprintf(buffer, ", 0x%02x", (unsigned char) (self->ob_bytes[i]));
562 str = PyString_FromString((i == 0) ? buffer+2 : buffer);
563 if (str == NULL)
564 goto error;
565 err = PyList_Append(list, str);
566 Py_DECREF(str);
567 if (err < 0)
568 goto error;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000569 }
570
571 str = PyString_FromString("])");
572 if (str == NULL)
Guido van Rossumd624f182006-04-24 13:47:05 +0000573 goto error;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000574
575 err = PyList_Append(list, str);
576 Py_DECREF(str);
577 if (err < 0)
Guido van Rossumd624f182006-04-24 13:47:05 +0000578 goto error;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000579
580 str = PyString_FromString("");
581 if (str == NULL)
Guido van Rossumd624f182006-04-24 13:47:05 +0000582 goto error;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000583
584 result = _PyString_Join(str, list);
585 Py_DECREF(str);
586 Py_DECREF(list);
587 return result;
588
589 error:
590 /* Error handling when list != NULL */
591 Py_DECREF(list);
592 return NULL;
593}
594
595static PyObject *
Guido van Rossumd624f182006-04-24 13:47:05 +0000596bytes_str(PyBytesObject *self)
597{
598 return PyString_FromStringAndSize(self->ob_bytes, self->ob_size);
599}
600
601static PyObject *
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000602bytes_richcompare(PyBytesObject *self, PyBytesObject *other, int op)
603{
604 PyObject *res;
605 int minsize;
606 int cmp;
607
608 if (!PyBytes_Check(self) || !PyBytes_Check(other)) {
Guido van Rossumd624f182006-04-24 13:47:05 +0000609 Py_INCREF(Py_NotImplemented);
610 return Py_NotImplemented;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000611 }
612
613 if (self->ob_size != other->ob_size && (op == Py_EQ || op == Py_NE)) {
Guido van Rossumd624f182006-04-24 13:47:05 +0000614 /* Shortcut: if the lengths differ, the objects differ */
615 cmp = (op == Py_NE);
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000616 }
617 else {
Guido van Rossumd624f182006-04-24 13:47:05 +0000618 minsize = self->ob_size;
619 if (other->ob_size < minsize)
620 minsize = other->ob_size;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000621
Guido van Rossumd624f182006-04-24 13:47:05 +0000622 cmp = memcmp(self->ob_bytes, other->ob_bytes, minsize);
623 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000624
Guido van Rossumd624f182006-04-24 13:47:05 +0000625 if (cmp == 0) {
626 if (self->ob_size < other->ob_size)
627 cmp = -1;
628 else if (self->ob_size > other->ob_size)
629 cmp = 1;
630 }
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000631
Guido van Rossumd624f182006-04-24 13:47:05 +0000632 switch (op) {
633 case Py_LT: cmp = cmp < 0; break;
634 case Py_LE: cmp = cmp <= 0; break;
635 case Py_EQ: cmp = cmp == 0; break;
636 case Py_NE: cmp = cmp != 0; break;
637 case Py_GT: cmp = cmp > 0; break;
638 case Py_GE: cmp = cmp >= 0; break;
639 }
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000640 }
641
642 res = cmp ? Py_True : Py_False;
643 Py_INCREF(res);
644 return res;
645}
646
647static void
648bytes_dealloc(PyBytesObject *self)
649{
Guido van Rossumd624f182006-04-24 13:47:05 +0000650 if (self->ob_bytes != 0) {
651 PyMem_Free(self->ob_bytes);
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000652 }
653 self->ob_type->tp_free((PyObject *)self);
654}
655
Guido van Rossumd624f182006-04-24 13:47:05 +0000656static Py_ssize_t
657bytes_getbuffer(PyBytesObject *self, Py_ssize_t index, const void **ptr)
658{
659 if (index != 0) {
660 PyErr_SetString(PyExc_SystemError,
661 "accessing non-existent string segment");
662 return -1;
663 }
664 *ptr = (void *)self->ob_bytes;
665 return self->ob_size;
666}
667
668static Py_ssize_t
669bytes_getsegcount(PyStringObject *self, Py_ssize_t *lenp)
670{
671 if (lenp)
672 *lenp = self->ob_size;
673 return 1;
674}
675
676PyDoc_STRVAR(decode_doc,
677"B.decode([encoding[,errors]]) -> unicode obect.\n\
678\n\
679Decodes B using the codec registered for encoding. encoding defaults\n\
680to the default encoding. errors may be given to set a different error\n\
681handling scheme. Default is 'strict' meaning that encoding errors raise\n\
682a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
683as well as any other name registerd with codecs.register_error that is\n\
684able to handle UnicodeDecodeErrors.");
685
686static PyObject *
687bytes_decode(PyObject *self, PyObject *args)
688{
689 const char *encoding = NULL;
690 const char *errors = NULL;
691
692 if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors))
693 return NULL;
694 if (encoding == NULL)
695 encoding = PyUnicode_GetDefaultEncoding();
696 return PyCodec_Decode(self, encoding, errors);
697}
698
Guido van Rossuma0867f72006-05-05 04:34:18 +0000699PyDoc_STRVAR(alloc_doc,
700"B.__alloc__() -> int\n\
701\n\
702Returns the number of bytes actually allocated.");
703
704static PyObject *
705bytes_alloc(PyBytesObject *self)
706{
707 return PyInt_FromSsize_t(self->ob_alloc);
708}
709
Guido van Rossum20188312006-05-05 15:15:40 +0000710PyDoc_STRVAR(join_doc,
711"bytes.join(iterable_of_bytes) -> bytes\n\
712\n\
713Concatenates any number of bytes objects. Example:\n\
714bytes.join([bytes('ab'), bytes('pq'), bytes('rs')]) -> bytes('abpqrs').");
715
716static PyObject *
717bytes_join(PyObject *cls, PyObject *it)
718{
719 PyObject *seq;
720 Py_ssize_t i;
721 Py_ssize_t n;
722 PyObject **items;
723 Py_ssize_t totalsize = 0;
724 PyObject *result;
725 char *dest;
726
727 seq = PySequence_Fast(it, "can only join an iterable");
728 if (seq == NULL)
729 return NULL;
730 n = PySequence_Fast_GET_SIZE(seq);
731 items = PySequence_Fast_ITEMS(seq);
732
733 /* Compute the total size, and check that they are all bytes */
734 for (i = 0; i < n; i++) {
735 PyObject *obj = items[i];
736 if (!PyBytes_Check(obj)) {
737 PyErr_Format(PyExc_TypeError,
738 "can only join an iterable of bytes "
Guido van Rossum3cf5b1e2006-07-27 21:53:35 +0000739 "(item %ld has type '%.100s')",
740 /* XXX %ld isn't right on Win64 */
741 (long)i, obj->ob_type->tp_name);
Guido van Rossum20188312006-05-05 15:15:40 +0000742 goto error;
743 }
744 totalsize += PyBytes_GET_SIZE(obj);
745 if (totalsize < 0) {
746 PyErr_NoMemory();
747 goto error;
748 }
749 }
750
751 /* Allocate the result, and copy the bytes */
752 result = PyBytes_FromStringAndSize(NULL, totalsize);
753 if (result == NULL)
754 goto error;
755 dest = PyBytes_AS_STRING(result);
756 for (i = 0; i < n; i++) {
757 PyObject *obj = items[i];
758 Py_ssize_t size = PyBytes_GET_SIZE(obj);
759 memcpy(dest, PyBytes_AS_STRING(obj), size);
760 dest += size;
761 }
762
763 /* Done */
764 Py_DECREF(seq);
765 return result;
766
767 /* Error handling */
768 error:
769 Py_DECREF(seq);
770 return NULL;
771}
772
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000773static PySequenceMethods bytes_as_sequence = {
Guido van Rossumd624f182006-04-24 13:47:05 +0000774 (lenfunc)bytes_length, /*sq_length*/
775 (binaryfunc)bytes_concat, /*sq_concat*/
776 (ssizeargfunc)bytes_repeat, /*sq_repeat*/
777 (ssizeargfunc)bytes_getitem, /*sq_item*/
778 (ssizessizeargfunc)bytes_getslice, /*sq_slice*/
779 (ssizeobjargproc)bytes_setitem, /*sq_ass_item*/
780 (ssizessizeobjargproc)bytes_setslice, /* sq_ass_slice */
Guido van Rossumd624f182006-04-24 13:47:05 +0000781 (objobjproc)bytes_contains, /* sq_contains */
Guido van Rossum13e57212006-04-27 22:54:26 +0000782 (binaryfunc)bytes_iconcat, /* sq_inplace_concat */
783 (ssizeargfunc)bytes_irepeat, /* sq_inplace_repeat */
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000784};
785
786static PyMappingMethods bytes_as_mapping = {
Guido van Rossumd624f182006-04-24 13:47:05 +0000787 (lenfunc)bytes_length,
788 (binaryfunc)0,
789 0,
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000790};
791
792static PyBufferProcs bytes_as_buffer = {
Guido van Rossumd624f182006-04-24 13:47:05 +0000793 (readbufferproc)bytes_getbuffer,
794 (writebufferproc)bytes_getbuffer,
795 (segcountproc)bytes_getsegcount,
796 /* XXX Bytes are not characters! But we need to implement
797 bf_getcharbuffer() so we can be used as 't#' argument to codecs. */
798 (charbufferproc)bytes_getbuffer,
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000799};
800
801static PyMethodDef
802bytes_methods[] = {
Guido van Rossumd624f182006-04-24 13:47:05 +0000803 {"decode", (PyCFunction)bytes_decode, METH_VARARGS, decode_doc},
Guido van Rossuma0867f72006-05-05 04:34:18 +0000804 {"__alloc__", (PyCFunction)bytes_alloc, METH_NOARGS, alloc_doc},
Guido van Rossum20188312006-05-05 15:15:40 +0000805 {"join", (PyCFunction)bytes_join, METH_O|METH_CLASS, join_doc},
Guido van Rossuma0867f72006-05-05 04:34:18 +0000806 {NULL}
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000807};
808
809PyDoc_STRVAR(bytes_doc,
810"bytes([iterable]) -> new array of bytes.\n\
811\n\
812If an argument is given it must be an iterable yielding ints in range(256).");
813
814PyTypeObject PyBytes_Type = {
815 PyObject_HEAD_INIT(&PyType_Type)
816 0,
817 "bytes",
818 sizeof(PyBytesObject),
819 0,
Guido van Rossumd624f182006-04-24 13:47:05 +0000820 (destructor)bytes_dealloc, /* tp_dealloc */
821 0, /* tp_print */
822 0, /* tp_getattr */
823 0, /* tp_setattr */
824 0, /* tp_compare */
825 (reprfunc)bytes_repr, /* tp_repr */
826 0, /* tp_as_number */
827 &bytes_as_sequence, /* tp_as_sequence */
828 &bytes_as_mapping, /* tp_as_mapping */
Guido van Rossum50e9fb92006-08-17 05:42:55 +0000829 0, /* tp_hash */
Guido van Rossumd624f182006-04-24 13:47:05 +0000830 0, /* tp_call */
831 (reprfunc)bytes_str, /* tp_str */
832 PyObject_GenericGetAttr, /* tp_getattro */
833 0, /* tp_setattro */
834 &bytes_as_buffer, /* tp_as_buffer */
Guido van Rossum3cf5b1e2006-07-27 21:53:35 +0000835 Py_TPFLAGS_DEFAULT, /* tp_flags */
Guido van Rossumd624f182006-04-24 13:47:05 +0000836 /* bytes is 'final' or 'sealed' */
837 bytes_doc, /* tp_doc */
838 0, /* tp_traverse */
839 0, /* tp_clear */
840 (richcmpfunc)bytes_richcompare, /* tp_richcompare */
841 0, /* tp_weaklistoffset */
842 0, /* tp_iter */
843 0, /* tp_iternext */
844 bytes_methods, /* tp_methods */
845 0, /* tp_members */
846 0, /* tp_getset */
847 0, /* tp_base */
848 0, /* tp_dict */
849 0, /* tp_descr_get */
850 0, /* tp_descr_set */
851 0, /* tp_dictoffset */
852 (initproc)bytes_init, /* tp_init */
853 PyType_GenericAlloc, /* tp_alloc */
854 PyType_GenericNew, /* tp_new */
855 PyObject_Del, /* tp_free */
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000856};