blob: d6cce6d49ec9cee38e3a3ae72685303cb767cb16 [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
Thomas Woutersd204a712006-08-22 13:41:17 +0000248 ival = PyNumber_AsSsize_t(value, PyExc_ValueError);
Guido van Rossum13e57212006-04-27 22:54:26 +0000249 if (ival == -1 && PyErr_Occurred())
250 return -1;
Guido van Rossum13e57212006-04-27 22:54:26 +0000251 if (ival < 0 || ival >= 256) {
252 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
253 return -1;
254 }
255
256 return memchr(self->ob_bytes, ival, self->ob_size) != NULL;
257}
258
259static PyObject *
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000260bytes_getitem(PyBytesObject *self, Py_ssize_t i)
261{
262 if (i < 0)
Guido van Rossumd624f182006-04-24 13:47:05 +0000263 i += self->ob_size;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000264 if (i < 0 || i >= self->ob_size) {
Guido van Rossumd624f182006-04-24 13:47:05 +0000265 PyErr_SetString(PyExc_IndexError, "bytes index out of range");
266 return NULL;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000267 }
Guido van Rossumd624f182006-04-24 13:47:05 +0000268 return PyInt_FromLong((unsigned char)(self->ob_bytes[i]));
269}
270
271static PyObject *
272bytes_getslice(PyBytesObject *self, Py_ssize_t lo, Py_ssize_t hi)
273{
274 if (lo < 0)
275 lo = 0;
276 if (hi > self->ob_size)
277 hi = self->ob_size;
278 if (lo >= hi)
279 lo = hi = 0;
280 return PyBytes_FromStringAndSize(self->ob_bytes + lo, hi - lo);
281}
282
283static int
284bytes_setslice(PyBytesObject *self, Py_ssize_t lo, Py_ssize_t hi,
285 PyObject *values)
286{
287 int avail;
288 int needed;
289 char *bytes;
290
291 if (values == NULL) {
292 bytes = NULL;
293 needed = 0;
294 }
295 else if (values == (PyObject *)self || !PyBytes_Check(values)) {
296 /* Make a copy an call this function recursively */
297 int err;
298 values = PyBytes_FromObject(values);
299 if (values == NULL)
300 return -1;
301 err = bytes_setslice(self, lo, hi, values);
302 Py_DECREF(values);
303 return err;
304 }
305 else {
306 assert(PyBytes_Check(values));
307 bytes = ((PyBytesObject *)values)->ob_bytes;
308 needed = ((PyBytesObject *)values)->ob_size;
309 }
310
311 if (lo < 0)
312 lo = 0;
313 if (hi > self->ob_size)
314 hi = self->ob_size;
315
316 avail = hi - lo;
317 if (avail < 0)
318 lo = hi = avail = 0;
319
320 if (avail != needed) {
321 if (avail > needed) {
322 /*
323 0 lo hi old_size
324 | |<----avail----->|<-----tomove------>|
325 | |<-needed->|<-----tomove------>|
326 0 lo new_hi new_size
327 */
328 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
329 self->ob_size - hi);
330 }
331 if (PyBytes_Resize((PyObject *)self,
332 self->ob_size + needed - avail) < 0)
333 return -1;
334 if (avail < needed) {
335 /*
336 0 lo hi old_size
337 | |<-avail->|<-----tomove------>|
338 | |<----needed---->|<-----tomove------>|
339 0 lo new_hi new_size
340 */
341 memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
342 self->ob_size - lo - needed);
343 }
344 }
345
346 if (needed > 0)
347 memcpy(self->ob_bytes + lo, bytes, needed);
348
349 return 0;
350}
351
352static int
353bytes_setitem(PyBytesObject *self, Py_ssize_t i, PyObject *value)
354{
355 Py_ssize_t ival;
356
357 if (i < 0)
358 i += self->ob_size;
359
360 if (i < 0 || i >= self->ob_size) {
361 PyErr_SetString(PyExc_IndexError, "bytes index out of range");
362 return -1;
363 }
364
365 if (value == NULL)
366 return bytes_setslice(self, i, i+1, NULL);
367
Thomas Woutersd204a712006-08-22 13:41:17 +0000368 ival = PyNumber_AsSsize_t(value, PyExc_ValueError);
Guido van Rossumd624f182006-04-24 13:47:05 +0000369 if (ival == -1 && PyErr_Occurred())
370 return -1;
371
372 if (ival < 0 || ival >= 256) {
373 PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
374 return -1;
375 }
376
377 self->ob_bytes[i] = ival;
378 return 0;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000379}
380
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000381static int
382bytes_init(PyBytesObject *self, PyObject *args, PyObject *kwds)
383{
Guido van Rossumd624f182006-04-24 13:47:05 +0000384 static char *kwlist[] = {"source", "encoding", "errors", 0};
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000385 PyObject *arg = NULL;
Guido van Rossumd624f182006-04-24 13:47:05 +0000386 const char *encoding = NULL;
387 const char *errors = NULL;
388 Py_ssize_t count;
389 PyObject *it;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000390 PyObject *(*iternext)(PyObject *);
391
Guido van Rossuma0867f72006-05-05 04:34:18 +0000392 if (self->ob_size != 0) {
393 /* Empty previous contents (yes, do this first of all!) */
394 if (PyBytes_Resize((PyObject *)self, 0) < 0)
395 return -1;
396 }
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000397
Guido van Rossumd624f182006-04-24 13:47:05 +0000398 /* Parse arguments */
399 if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytes", kwlist,
400 &arg, &encoding, &errors))
401 return -1;
402
403 /* Make a quick exit if no first argument */
404 if (arg == NULL) {
405 if (encoding != NULL || errors != NULL) {
406 PyErr_SetString(PyExc_TypeError,
407 "encoding or errors without sequence argument");
408 return -1;
409 }
410 return 0;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000411 }
412
Guido van Rossumd624f182006-04-24 13:47:05 +0000413 if (PyUnicode_Check(arg)) {
414 /* Encode via the codec registry */
415 PyObject *encoded;
416 char *bytes;
417 Py_ssize_t size;
418 if (encoding == NULL)
419 encoding = PyUnicode_GetDefaultEncoding();
420 encoded = PyCodec_Encode(arg, encoding, errors);
421 if (encoded == NULL)
422 return -1;
423 if (!PyString_Check(encoded)) {
424 PyErr_Format(PyExc_TypeError,
425 "encoder did not return a string object (type=%.400s)",
426 encoded->ob_type->tp_name);
427 Py_DECREF(encoded);
428 return -1;
429 }
430 bytes = PyString_AS_STRING(encoded);
431 size = PyString_GET_SIZE(encoded);
Guido van Rossuma0867f72006-05-05 04:34:18 +0000432 if (size <= self->ob_alloc)
433 self->ob_size = size;
434 else if (PyBytes_Resize((PyObject *)self, size) < 0) {
Guido van Rossumd624f182006-04-24 13:47:05 +0000435 Py_DECREF(encoded);
436 return -1;
437 }
438 memcpy(self->ob_bytes, bytes, size);
439 Py_DECREF(encoded);
440 return 0;
441 }
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000442
Guido van Rossumd624f182006-04-24 13:47:05 +0000443 /* If it's not unicode, there can't be encoding or errors */
444 if (encoding != NULL || errors != NULL) {
445 PyErr_SetString(PyExc_TypeError,
446 "encoding or errors without a string argument");
447 return -1;
448 }
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000449
Guido van Rossumd624f182006-04-24 13:47:05 +0000450 /* Is it an int? */
Thomas Woutersd204a712006-08-22 13:41:17 +0000451 count = PyNumber_AsSsize_t(arg, PyExc_ValueError);
Guido van Rossumd624f182006-04-24 13:47:05 +0000452 if (count == -1 && PyErr_Occurred())
453 PyErr_Clear();
454 else {
455 if (count < 0) {
456 PyErr_SetString(PyExc_ValueError, "negative count");
457 return -1;
458 }
459 if (count > 0) {
460 if (PyBytes_Resize((PyObject *)self, count))
461 return -1;
462 memset(self->ob_bytes, 0, count);
463 }
464 return 0;
465 }
466
467 if (PyObject_CheckReadBuffer(arg)) {
468 const void *bytes;
469 Py_ssize_t size;
470 if (PyObject_AsReadBuffer(arg, &bytes, &size) < 0)
471 return -1;
472 if (PyBytes_Resize((PyObject *)self, size) < 0)
473 return -1;
474 memcpy(self->ob_bytes, bytes, size);
475 return 0;
476 }
477
478 /* XXX Optimize this if the arguments is a list, tuple */
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000479
480 /* Get the iterator */
481 it = PyObject_GetIter(arg);
482 if (it == NULL)
Guido van Rossumd624f182006-04-24 13:47:05 +0000483 return -1;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000484 iternext = *it->ob_type->tp_iternext;
485
486 /* Run the iterator to exhaustion */
487 for (;;) {
Guido van Rossumd624f182006-04-24 13:47:05 +0000488 PyObject *item;
489 Py_ssize_t value;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000490
Guido van Rossumd624f182006-04-24 13:47:05 +0000491 /* Get the next item */
492 item = iternext(it);
493 if (item == NULL) {
494 if (PyErr_Occurred()) {
495 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
496 goto error;
497 PyErr_Clear();
498 }
499 break;
500 }
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000501
Guido van Rossumd624f182006-04-24 13:47:05 +0000502 /* Interpret it as an int (__index__) */
Thomas Woutersd204a712006-08-22 13:41:17 +0000503 value = PyNumber_AsSsize_t(item, PyExc_ValueError);
Guido van Rossumd624f182006-04-24 13:47:05 +0000504 Py_DECREF(item);
505 if (value == -1 && PyErr_Occurred())
506 goto error;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000507
Guido van Rossumd624f182006-04-24 13:47:05 +0000508 /* Range check */
509 if (value < 0 || value >= 256) {
510 PyErr_SetString(PyExc_ValueError,
511 "bytes must be in range(0, 256)");
512 goto error;
513 }
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000514
Guido van Rossumd624f182006-04-24 13:47:05 +0000515 /* Append the byte */
Guido van Rossuma0867f72006-05-05 04:34:18 +0000516 if (self->ob_size < self->ob_alloc)
517 self->ob_size++;
518 else if (PyBytes_Resize((PyObject *)self, self->ob_size+1) < 0)
Guido van Rossumd624f182006-04-24 13:47:05 +0000519 goto error;
520 self->ob_bytes[self->ob_size-1] = value;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000521 }
522
523 /* Clean up and return success */
524 Py_DECREF(it);
525 return 0;
526
527 error:
528 /* Error handling when it != NULL */
529 Py_DECREF(it);
530 return -1;
531}
532
533static PyObject *
534bytes_repr(PyBytesObject *self)
535{
536 PyObject *list;
537 PyObject *str;
538 PyObject *result;
539 int err;
540 int i;
541
542 if (self->ob_size == 0)
Guido van Rossumd624f182006-04-24 13:47:05 +0000543 return PyString_FromString("bytes()");
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000544
545 list = PyList_New(0);
546 if (list == NULL)
Guido van Rossumd624f182006-04-24 13:47:05 +0000547 return NULL;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000548
549 str = PyString_FromString("bytes([");
550 if (str == NULL)
Guido van Rossumd624f182006-04-24 13:47:05 +0000551 goto error;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000552
553 err = PyList_Append(list, str);
554 Py_DECREF(str);
555 if (err < 0)
Guido van Rossumd624f182006-04-24 13:47:05 +0000556 goto error;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000557
558 for (i = 0; i < self->ob_size; i++) {
Guido van Rossumd624f182006-04-24 13:47:05 +0000559 char buffer[20];
560 sprintf(buffer, ", 0x%02x", (unsigned char) (self->ob_bytes[i]));
561 str = PyString_FromString((i == 0) ? buffer+2 : buffer);
562 if (str == NULL)
563 goto error;
564 err = PyList_Append(list, str);
565 Py_DECREF(str);
566 if (err < 0)
567 goto error;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000568 }
569
570 str = PyString_FromString("])");
571 if (str == NULL)
Guido van Rossumd624f182006-04-24 13:47:05 +0000572 goto error;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000573
574 err = PyList_Append(list, str);
575 Py_DECREF(str);
576 if (err < 0)
Guido van Rossumd624f182006-04-24 13:47:05 +0000577 goto error;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000578
579 str = PyString_FromString("");
580 if (str == NULL)
Guido van Rossumd624f182006-04-24 13:47:05 +0000581 goto error;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000582
583 result = _PyString_Join(str, list);
584 Py_DECREF(str);
585 Py_DECREF(list);
586 return result;
587
588 error:
589 /* Error handling when list != NULL */
590 Py_DECREF(list);
591 return NULL;
592}
593
594static PyObject *
Guido van Rossumd624f182006-04-24 13:47:05 +0000595bytes_str(PyBytesObject *self)
596{
597 return PyString_FromStringAndSize(self->ob_bytes, self->ob_size);
598}
599
600static PyObject *
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000601bytes_richcompare(PyBytesObject *self, PyBytesObject *other, int op)
602{
603 PyObject *res;
604 int minsize;
605 int cmp;
606
607 if (!PyBytes_Check(self) || !PyBytes_Check(other)) {
Guido van Rossumd624f182006-04-24 13:47:05 +0000608 Py_INCREF(Py_NotImplemented);
609 return Py_NotImplemented;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000610 }
611
612 if (self->ob_size != other->ob_size && (op == Py_EQ || op == Py_NE)) {
Guido van Rossumd624f182006-04-24 13:47:05 +0000613 /* Shortcut: if the lengths differ, the objects differ */
614 cmp = (op == Py_NE);
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000615 }
616 else {
Guido van Rossumd624f182006-04-24 13:47:05 +0000617 minsize = self->ob_size;
618 if (other->ob_size < minsize)
619 minsize = other->ob_size;
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000620
Guido van Rossumd624f182006-04-24 13:47:05 +0000621 cmp = memcmp(self->ob_bytes, other->ob_bytes, minsize);
622 /* In ISO C, memcmp() guarantees to use unsigned bytes! */
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000623
Guido van Rossumd624f182006-04-24 13:47:05 +0000624 if (cmp == 0) {
625 if (self->ob_size < other->ob_size)
626 cmp = -1;
627 else if (self->ob_size > other->ob_size)
628 cmp = 1;
629 }
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000630
Guido van Rossumd624f182006-04-24 13:47:05 +0000631 switch (op) {
632 case Py_LT: cmp = cmp < 0; break;
633 case Py_LE: cmp = cmp <= 0; break;
634 case Py_EQ: cmp = cmp == 0; break;
635 case Py_NE: cmp = cmp != 0; break;
636 case Py_GT: cmp = cmp > 0; break;
637 case Py_GE: cmp = cmp >= 0; break;
638 }
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000639 }
640
641 res = cmp ? Py_True : Py_False;
642 Py_INCREF(res);
643 return res;
644}
645
646static void
647bytes_dealloc(PyBytesObject *self)
648{
Guido van Rossumd624f182006-04-24 13:47:05 +0000649 if (self->ob_bytes != 0) {
650 PyMem_Free(self->ob_bytes);
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000651 }
652 self->ob_type->tp_free((PyObject *)self);
653}
654
Guido van Rossumd624f182006-04-24 13:47:05 +0000655static Py_ssize_t
656bytes_getbuffer(PyBytesObject *self, Py_ssize_t index, const void **ptr)
657{
658 if (index != 0) {
659 PyErr_SetString(PyExc_SystemError,
660 "accessing non-existent string segment");
661 return -1;
662 }
663 *ptr = (void *)self->ob_bytes;
664 return self->ob_size;
665}
666
667static Py_ssize_t
668bytes_getsegcount(PyStringObject *self, Py_ssize_t *lenp)
669{
670 if (lenp)
671 *lenp = self->ob_size;
672 return 1;
673}
674
675PyDoc_STRVAR(decode_doc,
676"B.decode([encoding[,errors]]) -> unicode obect.\n\
677\n\
678Decodes B using the codec registered for encoding. encoding defaults\n\
679to the default encoding. errors may be given to set a different error\n\
680handling scheme. Default is 'strict' meaning that encoding errors raise\n\
681a UnicodeDecodeError. Other possible values are 'ignore' and 'replace'\n\
682as well as any other name registerd with codecs.register_error that is\n\
683able to handle UnicodeDecodeErrors.");
684
685static PyObject *
686bytes_decode(PyObject *self, PyObject *args)
687{
688 const char *encoding = NULL;
689 const char *errors = NULL;
690
691 if (!PyArg_ParseTuple(args, "|ss:decode", &encoding, &errors))
692 return NULL;
693 if (encoding == NULL)
694 encoding = PyUnicode_GetDefaultEncoding();
695 return PyCodec_Decode(self, encoding, errors);
696}
697
Guido van Rossuma0867f72006-05-05 04:34:18 +0000698PyDoc_STRVAR(alloc_doc,
699"B.__alloc__() -> int\n\
700\n\
701Returns the number of bytes actually allocated.");
702
703static PyObject *
704bytes_alloc(PyBytesObject *self)
705{
706 return PyInt_FromSsize_t(self->ob_alloc);
707}
708
Guido van Rossum20188312006-05-05 15:15:40 +0000709PyDoc_STRVAR(join_doc,
710"bytes.join(iterable_of_bytes) -> bytes\n\
711\n\
712Concatenates any number of bytes objects. Example:\n\
713bytes.join([bytes('ab'), bytes('pq'), bytes('rs')]) -> bytes('abpqrs').");
714
715static PyObject *
716bytes_join(PyObject *cls, PyObject *it)
717{
718 PyObject *seq;
719 Py_ssize_t i;
720 Py_ssize_t n;
721 PyObject **items;
722 Py_ssize_t totalsize = 0;
723 PyObject *result;
724 char *dest;
725
726 seq = PySequence_Fast(it, "can only join an iterable");
727 if (seq == NULL)
728 return NULL;
729 n = PySequence_Fast_GET_SIZE(seq);
730 items = PySequence_Fast_ITEMS(seq);
731
732 /* Compute the total size, and check that they are all bytes */
733 for (i = 0; i < n; i++) {
734 PyObject *obj = items[i];
735 if (!PyBytes_Check(obj)) {
736 PyErr_Format(PyExc_TypeError,
737 "can only join an iterable of bytes "
Guido van Rossum3cf5b1e2006-07-27 21:53:35 +0000738 "(item %ld has type '%.100s')",
739 /* XXX %ld isn't right on Win64 */
740 (long)i, obj->ob_type->tp_name);
Guido van Rossum20188312006-05-05 15:15:40 +0000741 goto error;
742 }
743 totalsize += PyBytes_GET_SIZE(obj);
744 if (totalsize < 0) {
745 PyErr_NoMemory();
746 goto error;
747 }
748 }
749
750 /* Allocate the result, and copy the bytes */
751 result = PyBytes_FromStringAndSize(NULL, totalsize);
752 if (result == NULL)
753 goto error;
754 dest = PyBytes_AS_STRING(result);
755 for (i = 0; i < n; i++) {
756 PyObject *obj = items[i];
757 Py_ssize_t size = PyBytes_GET_SIZE(obj);
758 memcpy(dest, PyBytes_AS_STRING(obj), size);
759 dest += size;
760 }
761
762 /* Done */
763 Py_DECREF(seq);
764 return result;
765
766 /* Error handling */
767 error:
768 Py_DECREF(seq);
769 return NULL;
770}
771
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000772static PySequenceMethods bytes_as_sequence = {
Guido van Rossumd624f182006-04-24 13:47:05 +0000773 (lenfunc)bytes_length, /*sq_length*/
774 (binaryfunc)bytes_concat, /*sq_concat*/
775 (ssizeargfunc)bytes_repeat, /*sq_repeat*/
776 (ssizeargfunc)bytes_getitem, /*sq_item*/
777 (ssizessizeargfunc)bytes_getslice, /*sq_slice*/
778 (ssizeobjargproc)bytes_setitem, /*sq_ass_item*/
779 (ssizessizeobjargproc)bytes_setslice, /* sq_ass_slice */
Guido van Rossumd624f182006-04-24 13:47:05 +0000780 (objobjproc)bytes_contains, /* sq_contains */
Guido van Rossum13e57212006-04-27 22:54:26 +0000781 (binaryfunc)bytes_iconcat, /* sq_inplace_concat */
782 (ssizeargfunc)bytes_irepeat, /* sq_inplace_repeat */
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000783};
784
785static PyMappingMethods bytes_as_mapping = {
Guido van Rossumd624f182006-04-24 13:47:05 +0000786 (lenfunc)bytes_length,
787 (binaryfunc)0,
788 0,
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000789};
790
791static PyBufferProcs bytes_as_buffer = {
Guido van Rossumd624f182006-04-24 13:47:05 +0000792 (readbufferproc)bytes_getbuffer,
793 (writebufferproc)bytes_getbuffer,
794 (segcountproc)bytes_getsegcount,
795 /* XXX Bytes are not characters! But we need to implement
796 bf_getcharbuffer() so we can be used as 't#' argument to codecs. */
797 (charbufferproc)bytes_getbuffer,
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000798};
799
800static PyMethodDef
801bytes_methods[] = {
Guido van Rossumd624f182006-04-24 13:47:05 +0000802 {"decode", (PyCFunction)bytes_decode, METH_VARARGS, decode_doc},
Guido van Rossuma0867f72006-05-05 04:34:18 +0000803 {"__alloc__", (PyCFunction)bytes_alloc, METH_NOARGS, alloc_doc},
Guido van Rossum20188312006-05-05 15:15:40 +0000804 {"join", (PyCFunction)bytes_join, METH_O|METH_CLASS, join_doc},
Guido van Rossuma0867f72006-05-05 04:34:18 +0000805 {NULL}
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000806};
807
808PyDoc_STRVAR(bytes_doc,
809"bytes([iterable]) -> new array of bytes.\n\
810\n\
811If an argument is given it must be an iterable yielding ints in range(256).");
812
813PyTypeObject PyBytes_Type = {
814 PyObject_HEAD_INIT(&PyType_Type)
815 0,
816 "bytes",
817 sizeof(PyBytesObject),
818 0,
Guido van Rossumd624f182006-04-24 13:47:05 +0000819 (destructor)bytes_dealloc, /* tp_dealloc */
820 0, /* tp_print */
821 0, /* tp_getattr */
822 0, /* tp_setattr */
823 0, /* tp_compare */
824 (reprfunc)bytes_repr, /* tp_repr */
825 0, /* tp_as_number */
826 &bytes_as_sequence, /* tp_as_sequence */
827 &bytes_as_mapping, /* tp_as_mapping */
Guido van Rossum50e9fb92006-08-17 05:42:55 +0000828 0, /* tp_hash */
Guido van Rossumd624f182006-04-24 13:47:05 +0000829 0, /* tp_call */
830 (reprfunc)bytes_str, /* tp_str */
831 PyObject_GenericGetAttr, /* tp_getattro */
832 0, /* tp_setattro */
833 &bytes_as_buffer, /* tp_as_buffer */
Guido van Rossum3cf5b1e2006-07-27 21:53:35 +0000834 Py_TPFLAGS_DEFAULT, /* tp_flags */
Guido van Rossumd624f182006-04-24 13:47:05 +0000835 /* bytes is 'final' or 'sealed' */
836 bytes_doc, /* tp_doc */
837 0, /* tp_traverse */
838 0, /* tp_clear */
839 (richcmpfunc)bytes_richcompare, /* tp_richcompare */
840 0, /* tp_weaklistoffset */
841 0, /* tp_iter */
842 0, /* tp_iternext */
843 bytes_methods, /* tp_methods */
844 0, /* tp_members */
845 0, /* tp_getset */
846 0, /* tp_base */
847 0, /* tp_dict */
848 0, /* tp_descr_get */
849 0, /* tp_descr_set */
850 0, /* tp_dictoffset */
851 (initproc)bytes_init, /* tp_init */
852 PyType_GenericAlloc, /* tp_alloc */
853 PyType_GenericNew, /* tp_new */
854 PyObject_Del, /* tp_free */
Guido van Rossum4dfe8a12006-04-22 23:28:04 +0000855};