1 #include <Python.h> 2 #include "mod_defs.h" 3 #include "bitstream.h" 4 #include "huffman.h" 5 #include "buffer.h" 6 #include "mod_bitstream.h" 7 8 /******************************************************** 9 Audio Tools, a module and set of tools for manipulating audio data 10 Copyright (C) 2007-2014 Brian Langenberger 11 12 This program is free software; you can redistribute it and/or modify 13 it under the terms of the GNU General Public License as published by 14 the Free Software Foundation; either version 2 of the License, or 15 (at your option) any later version. 16 17 This program is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU General Public License for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with this program; if not, write to the Free Software 24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 25 *******************************************************/ 26 27 #if PY_MAJOR_VERSION >= 3 28 #ifndef PyInt_AsLong 29 #define PyInt_AsLong PyLong_AsLong 30 #endif 31 #ifndef PyInt_FromLong 32 #define PyInt_FromLong PyLong_FromLong 33 #endif 34 #endif 35 36 MOD_INIT(bitstream) 37 { 38 PyObject* m; 39 40 MOD_DEF(m, "bitstream", "a bitstream handling module", module_methods) 41 42 bitstream_BitstreamReaderType.tp_new = PyType_GenericNew; 43 if (PyType_Ready(&bitstream_BitstreamReaderType) < 0) 44 return MOD_ERROR_VAL; 45 46 bitstream_HuffmanTreeType.tp_new = PyType_GenericNew; 47 if (PyType_Ready(&bitstream_HuffmanTreeType) < 0) 48 return MOD_ERROR_VAL; 49 50 bitstream_BitstreamReaderPositionType.tp_new = PyType_GenericNew; 51 if (PyType_Ready(&bitstream_BitstreamReaderPositionType) < 0) 52 return MOD_ERROR_VAL; 53 54 bitstream_BitstreamWriterType.tp_new = PyType_GenericNew; 55 if (PyType_Ready(&bitstream_BitstreamWriterType) < 0) 56 return MOD_ERROR_VAL; 57 58 bitstream_BitstreamRecorderType.tp_new = PyType_GenericNew; 59 if (PyType_Ready(&bitstream_BitstreamRecorderType) < 0) 60 return MOD_ERROR_VAL; 61 62 bitstream_BitstreamWriterPositionType.tp_new = PyType_GenericNew; 63 if (PyType_Ready(&bitstream_BitstreamWriterPositionType) < 0) 64 return MOD_ERROR_VAL; 65 66 Py_INCREF(&bitstream_BitstreamReaderType); 67 PyModule_AddObject(m, "BitstreamReader", 68 (PyObject *)&bitstream_BitstreamReaderType); 69 70 Py_INCREF(&bitstream_HuffmanTreeType); 71 PyModule_AddObject(m, "HuffmanTree", 72 (PyObject *)&bitstream_HuffmanTreeType); 73 74 Py_INCREF(&bitstream_BitstreamReaderPositionType); 75 PyModule_AddObject(m, "BitstreamReaderPosition", 76 (PyObject *)&bitstream_BitstreamReaderPositionType); 77 78 Py_INCREF(&bitstream_BitstreamWriterType); 79 PyModule_AddObject(m, "BitstreamWriter", 80 (PyObject *)&bitstream_BitstreamWriterType); 81 82 Py_INCREF(&bitstream_BitstreamRecorderType); 83 PyModule_AddObject(m, "BitstreamRecorder", 84 (PyObject *)&bitstream_BitstreamRecorderType); 85 86 Py_INCREF(&bitstream_BitstreamWriterPositionType); 87 PyModule_AddObject(m, "BitstreamWriterPosition", 88 (PyObject *)&bitstream_BitstreamWriterPositionType); 89 90 return MOD_SUCCESS_VAL(m); 91 } 92 93 static PyObject* 94 brpy_read_unsigned(BitstreamReader *br, unsigned bits) 95 { 96 if (!setjmp(*br_try(br))) { 97 if (bits <= (sizeof(unsigned int) * 8)) { 98 /*if bits are small enough, first try regular read*/ 99 const unsigned result = br->read(br, bits); 100 br_etry(br); 101 return Py_BuildValue("I", result); 102 } else if (bits <= (sizeof(uint64_t) * 8)) { 103 /*or try read_64*/ 104 const uint64_t result = br->read_64(br, bits); 105 br_etry(br); 106 return Py_BuildValue("K", result); 107 } else { 108 /*finally, try read_bigint*/ 109 mpz_t result; 110 char *result_str; 111 PyObject *result_obj; 112 113 mpz_init(result); 114 115 /*perform read*/ 116 if (!setjmp(*br_try(br))) { 117 br->read_bigint(br, bits, result); 118 br_etry(br); 119 } else { 120 /*ensure result gets cleared before re-raising error*/ 121 br_etry(br); 122 mpz_clear(result); 123 br_abort(br); 124 } 125 126 br_etry(br); 127 128 /*serialize result as string*/ 129 result_str = mpz_get_str(NULL, 10, result); 130 mpz_clear(result); 131 132 /*convert to Python long*/ 133 result_obj = PyLong_FromString(result_str, NULL, 10); 134 free(result_str); 135 136 /*return result*/ 137 return result_obj; 138 } 139 } else { 140 br_etry(br); 141 PyErr_SetString(PyExc_IOError, "I/O error reading stream"); 142 return NULL; 143 } 144 } 145 146 static PyObject* 147 brpy_read_signed(BitstreamReader *br, unsigned bits) 148 { 149 if (!setjmp(*br_try(br))) { 150 if (bits <= (sizeof(int) * 8)) { 151 /*if bits are small enough, first try regular read*/ 152 const int result = br->read_signed(br, bits); 153 br_etry(br); 154 return Py_BuildValue("i", result); 155 } else if (bits <= (sizeof(uint64_t) * 8)) { 156 /*or try read_64*/ 157 const int64_t result = br->read_signed_64(br, bits); 158 br_etry(br); 159 return Py_BuildValue("L", result); 160 } else { 161 /*finally, try read_signed_bigint*/ 162 163 mpz_t result; 164 char *result_str; 165 PyObject *result_obj; 166 167 mpz_init(result); 168 169 if (!setjmp(*br_try(br))) { 170 br->read_signed_bigint(br, bits, result); 171 br_etry(br); 172 } else { 173 /*ensure result gets cleared before re-raising error*/ 174 br_etry(br); 175 mpz_clear(result); 176 br_abort(br); 177 } 178 179 br_etry(br); 180 181 /*serialize result as string*/ 182 result_str = mpz_get_str(NULL, 10, result); 183 mpz_clear(result); 184 185 /*convert to Python long*/ 186 result_obj = PyLong_FromString(result_str, NULL, 10); 187 free(result_str); 188 189 /*return result*/ 190 return result_obj; 191 } 192 } else { 193 br_etry(br); 194 PyErr_SetString(PyExc_IOError, "I/O error reading stream"); 195 return NULL; 196 } 197 } 198 199 static PyObject* 200 BitstreamReader_read(bitstream_BitstreamReader *self, PyObject *args) 201 { 202 int count; 203 204 if (!PyArg_ParseTuple(args, "i", &count)) { 205 return NULL; 206 } else if (count < 0) { 207 PyErr_SetString(PyExc_ValueError, "count must be >= 0"); 208 return NULL; 209 } 210 211 return brpy_read_unsigned(self->bitstream, (unsigned)count); 212 } 213 214 static PyObject* 215 BitstreamReader_read_signed(bitstream_BitstreamReader *self, PyObject *args) 216 { 217 int count; 218 219 if (!PyArg_ParseTuple(args, "i", &count)) { 220 return NULL; 221 } else if (count <= 0) { 222 PyErr_SetString(PyExc_ValueError, "count must be > 0"); 223 return NULL; 224 } 225 226 return brpy_read_signed(self->bitstream, (unsigned)count); 227 } 228 229 static PyObject* 230 BitstreamReader_skip(bitstream_BitstreamReader *self, PyObject *args) 231 { 232 int count; 233 234 if (!PyArg_ParseTuple(args, "i", &count)) { 235 return NULL; 236 } else if (count < 0) { 237 PyErr_SetString(PyExc_ValueError, "count must be >= 0"); 238 return NULL; 239 } 240 241 if (!setjmp(*br_try(self->bitstream))) { 242 self->bitstream->skip(self->bitstream, (unsigned)count); 243 br_etry(self->bitstream); 244 Py_INCREF(Py_None); 245 return Py_None; 246 } else { 247 br_etry(self->bitstream); 248 PyErr_SetString(PyExc_IOError, "I/O error reading stream"); 249 return NULL; 250 } 251 } 252 253 static PyObject* 254 BitstreamReader_skip_bytes(bitstream_BitstreamReader *self, PyObject *args) 255 { 256 PyObject *count; 257 258 if (!PyArg_ParseTuple(args, "O", &count)) { 259 return NULL; 260 } 261 262 if (brpy_skip_bytes_obj(self->bitstream, count)) { 263 return NULL; 264 } else { 265 Py_INCREF(Py_None); 266 return Py_None; 267 } 268 } 269 270 static PyObject* 271 BitstreamReader_byte_align(bitstream_BitstreamReader *self, PyObject *args) 272 { 273 self->bitstream->byte_align(self->bitstream); 274 275 Py_INCREF(Py_None); 276 return Py_None; 277 } 278 279 static PyObject* 280 BitstreamReader_byte_aligned(bitstream_BitstreamReader *self, PyObject *args) 281 { 282 return PyBool_FromLong(self->bitstream->byte_aligned(self->bitstream)); 283 } 284 285 286 static PyObject* 287 BitstreamReader_unread(bitstream_BitstreamReader *self, PyObject *args) 288 { 289 int unread_bit; 290 291 if (!PyArg_ParseTuple(args, "i", &unread_bit)) 292 return NULL; 293 294 if ((unread_bit != 0) && (unread_bit != 1)) { 295 PyErr_SetString(PyExc_ValueError, "unread bit must be 0 or 1"); 296 return NULL; 297 } 298 299 if (!setjmp(*br_try(self->bitstream))) { 300 self->bitstream->unread(self->bitstream, unread_bit); 301 br_etry(self->bitstream); 302 303 Py_INCREF(Py_None); 304 return Py_None; 305 } else { 306 br_etry(self->bitstream); 307 PyErr_SetString(PyExc_IOError, "I/O error unreading bit"); 308 return NULL; 309 } 310 } 311 312 313 static PyObject* 314 BitstreamReader_unary(bitstream_BitstreamReader *self, PyObject *args) 315 { 316 int stop_bit; 317 int result; 318 319 if (!PyArg_ParseTuple(args, "i", &stop_bit)) 320 return NULL; 321 322 if ((stop_bit != 0) && (stop_bit != 1)) { 323 PyErr_SetString(PyExc_ValueError, "stop bit must be 0 or 1"); 324 return NULL; 325 } 326 327 if (!setjmp(*br_try(self->bitstream))) { 328 result = self->bitstream->read_unary(self->bitstream, stop_bit); 329 br_etry(self->bitstream); 330 return Py_BuildValue("I", result); 331 } else { 332 br_etry(self->bitstream); 333 PyErr_SetString(PyExc_IOError, "I/O error reading stream"); 334 return NULL; 335 } 336 } 337 338 static PyObject* 339 BitstreamReader_skip_unary(bitstream_BitstreamReader *self, PyObject *args) 340 { 341 int stop_bit; 342 343 if (!PyArg_ParseTuple(args, "i", &stop_bit)) 344 return NULL; 345 346 if ((stop_bit != 0) && (stop_bit != 1)) { 347 PyErr_SetString(PyExc_ValueError, "stop bit must be 0 or 1"); 348 return NULL; 349 } 350 351 if (!setjmp(*br_try(self->bitstream))) { 352 self->bitstream->skip_unary(self->bitstream, stop_bit); 353 br_etry(self->bitstream); 354 Py_INCREF(Py_None); 355 return Py_None; 356 } else { 357 br_etry(self->bitstream); 358 PyErr_SetString(PyExc_IOError, "I/O error reading stream"); 359 return NULL; 360 } 361 } 362 363 static PyObject* 364 BitstreamReader_read_huffman_code(bitstream_BitstreamReader *self, 365 PyObject* args) 366 { 367 PyObject* huffman_tree_obj; 368 bitstream_HuffmanTree* huffman_tree; 369 int result; 370 371 if (!PyArg_ParseTuple(args, "O", &huffman_tree_obj)) 372 return NULL; 373 374 if (Py_TYPE(huffman_tree_obj) != &bitstream_HuffmanTreeType) { 375 PyErr_SetString(PyExc_TypeError, "argument must a HuffmanTree object"); 376 return NULL; 377 } 378 379 huffman_tree = (bitstream_HuffmanTree*)huffman_tree_obj; 380 381 if (!setjmp(*br_try(self->bitstream))) { 382 result = self->bitstream->read_huffman_code( 383 self->bitstream, huffman_tree->br_table); 384 385 br_etry(self->bitstream); 386 return Py_BuildValue("i", result); 387 } else { 388 br_etry(self->bitstream); 389 PyErr_SetString(PyExc_IOError, "I/O error reading stream"); 390 return NULL; 391 } 392 } 393 394 #define CHUNK_SIZE 4096 395 396 int 397 brpy_read_bytes_chunk(BitstreamReader *reader, 398 unsigned byte_count, 399 struct bs_buffer *buffer) 400 { 401 if (!setjmp(*br_try(reader))) { 402 while (byte_count > 0) { 403 const unsigned to_read = MIN(byte_count, CHUNK_SIZE); 404 static uint8_t temp[CHUNK_SIZE]; 405 406 reader->read_bytes(reader, temp, to_read); 407 buf_write(buffer, temp, to_read); 408 byte_count -= to_read; 409 } 410 411 br_etry(reader); 412 return 0; 413 } else { 414 br_etry(reader); 415 PyErr_SetString(PyExc_IOError, "I/O error reading stream"); 416 return 1; 417 } 418 } 419 420 PyObject* 421 brpy_read_bytes_min(PyObject *x, PyObject *y, long *minimum) 422 { 423 const int cmp = PyObject_RichCompareBool(x, y, Py_LT); 424 PyObject *smaller; 425 426 if (cmp == 0) { 427 smaller = y; 428 } else if (cmp == 1) { 429 smaller = x; 430 } else { 431 return NULL; 432 } 433 434 *minimum = PyInt_AsLong(smaller); 435 if ((*minimum != -1) || (!PyErr_Occurred())) { 436 return smaller; 437 } else { 438 return NULL; 439 } 440 } 441 442 static PyObject* 443 brpy_read_bytes_obj(BitstreamReader *reader, PyObject *byte_count) 444 { 445 PyObject *zero = PyInt_FromLong(0); 446 int zero_cmp = PyObject_RichCompareBool(byte_count, zero, Py_GE); 447 PyObject *chunk_size_obj; 448 struct bs_buffer *buffer; 449 450 /*ensure we've gotten a positive byte count*/ 451 if (zero_cmp == 0) { 452 PyErr_SetString(PyExc_ValueError, "byte count must be >= 0"); 453 Py_DECREF(zero); 454 return NULL; 455 } else if (zero_cmp == -1) { 456 /*some error during comparison*/ 457 Py_DECREF(zero); 458 return NULL; 459 } 460 461 /*allocate temporary objects and buffer*/ 462 Py_INCREF(byte_count); 463 buffer = buf_new(); 464 chunk_size_obj = PyInt_FromLong(MIN(UINT_MAX, LONG_MAX)); 465 466 /*read up to chunk_size bytes at a time from reader to buffer*/ 467 zero_cmp = PyObject_RichCompareBool(byte_count, zero, Py_GT); 468 while (zero_cmp == 1) { 469 /*the size of the chunk to read is chunk_size or byte_count, 470 whichever is smaller*/ 471 long to_read; 472 PyObject *to_read_obj; 473 PyObject *subtracted; 474 475 if ((to_read_obj = brpy_read_bytes_min(byte_count, 476 chunk_size_obj, 477 &to_read)) == NULL) { 478 /*some error occurred during comparison*/ 479 goto error; 480 } 481 482 /*perform read from reader to buffer based on size*/ 483 if (brpy_read_bytes_chunk(reader, (unsigned)to_read, buffer)) { 484 /*some error occurring during reading*/ 485 goto error; 486 } 487 488 /*deduct size of chunk from byte_count*/ 489 if ((subtracted = PyNumber_Subtract(byte_count, to_read_obj)) != NULL) { 490 Py_DECREF(byte_count); 491 byte_count = subtracted; 492 } else { 493 /*some error occurred during subtracting*/ 494 goto error; 495 } 496 497 /*check that byte_count is still greater than zero*/ 498 zero_cmp = PyObject_RichCompareBool(byte_count, zero, Py_GT); 499 } 500 501 if (zero_cmp == 0) { 502 /*byte_count no longer greater than 0*/ 503 504 /*convert buffer to Python string*/ 505 PyObject *string_obj = PyBytes_FromStringAndSize( 506 (char *)buf_window_start(buffer), 507 buf_window_size(buffer)); 508 509 /*deallocate temporary objects and buffer*/ 510 Py_DECREF(byte_count); 511 Py_DECREF(zero); 512 buf_close(buffer); 513 Py_DECREF(chunk_size_obj); 514 515 /*return Python string*/ 516 return string_obj; 517 } else { 518 /*some error occurred during comparison*/ 519 goto error; 520 } 521 522 error: 523 /*deallocate temporary objects and buffer*/ 524 Py_DECREF(byte_count); 525 Py_DECREF(zero); 526 buf_close(buffer); 527 Py_DECREF(chunk_size_obj); 528 529 /*forward error to caller*/ 530 return NULL; 531 } 532 533 534 int 535 brpy_skip_bytes_chunk(BitstreamReader *reader, 536 unsigned byte_count) 537 { 538 if (!setjmp(*br_try(reader))) { 539 reader->skip_bytes(reader, byte_count); 540 541 br_etry(reader); 542 return 0; 543 } else { 544 br_etry(reader); 545 PyErr_SetString(PyExc_IOError, "I/O error reading stream"); 546 return 1; 547 } 548 } 549 550 int 551 brpy_skip_bytes_obj(BitstreamReader *reader, PyObject *byte_count) 552 { 553 PyObject *zero = PyInt_FromLong(0); 554 int zero_cmp = PyObject_RichCompareBool(byte_count, zero, Py_GE); 555 PyObject *chunk_size_obj; 556 557 /*ensure we've gotten a positive byte count*/ 558 if (zero_cmp == 0) { 559 PyErr_SetString(PyExc_ValueError, "byte count must be >= 0"); 560 Py_DECREF(zero); 561 return 1; 562 } else if (zero_cmp == -1) { 563 /*some error during comparison*/ 564 Py_DECREF(zero); 565 return 1; 566 } 567 568 /*allocate temporary objects*/ 569 Py_INCREF(byte_count); 570 chunk_size_obj = PyInt_FromLong(MIN(UINT_MAX, LONG_MAX)); 571 572 /*read up to chunk_size bytes at a time from reader*/ 573 zero_cmp = PyObject_RichCompareBool(byte_count, zero, Py_GT); 574 while (zero_cmp == 1) { 575 /*the size of the chunk to read is chunk_size or byte_count, 576 whichever is smaller*/ 577 long to_read; 578 PyObject *to_read_obj; 579 PyObject *subtracted; 580 581 if ((to_read_obj = brpy_read_bytes_min(byte_count, 582 chunk_size_obj, 583 &to_read)) == NULL) { 584 /*some error occurred during comparison*/ 585 goto error; 586 } 587 588 /*perform read from reader to buffer based on size*/ 589 if (brpy_skip_bytes_chunk(reader, (unsigned)to_read)) { 590 /*some error occurring during reading*/ 591 goto error; 592 } 593 594 /*deduct size of chunk from byte_count*/ 595 if ((subtracted = PyNumber_Subtract(byte_count, to_read_obj)) != NULL) { 596 Py_DECREF(byte_count); 597 byte_count = subtracted; 598 } else { 599 /*some error occurred during subtracting*/ 600 goto error; 601 } 602 603 /*check that byte_count is still greater than zero*/ 604 zero_cmp = PyObject_RichCompareBool(byte_count, zero, Py_GT); 605 } 606 607 if (zero_cmp == 0) { 608 /*byte_count no longer greater than 0*/ 609 610 /*deallocate temporary objects and buffer*/ 611 Py_DECREF(byte_count); 612 Py_DECREF(zero); 613 Py_DECREF(chunk_size_obj); 614 615 /*return success*/ 616 return 0; 617 } else { 618 /*some error occurred during comparison*/ 619 goto error; 620 } 621 622 error: 623 /*deallocate temporary objects and buffer*/ 624 Py_DECREF(byte_count); 625 Py_DECREF(zero); 626 Py_DECREF(chunk_size_obj); 627 628 /*return read error*/ 629 return 1; 630 } 631 632 static PyObject* 633 brpy_read_bytes(BitstreamReader *reader, unsigned byte_count) 634 { 635 struct bs_buffer *buffer = buf_new(); 636 637 if (brpy_read_bytes_chunk(reader, byte_count, buffer)) { 638 /*some error occurring during reading*/ 639 640 /*deallocate buffer*/ 641 buf_close(buffer); 642 643 /*pass error along to caller*/ 644 return NULL; 645 } else { 646 /*convert buffer to Python string*/ 647 PyObject *string = PyBytes_FromStringAndSize( 648 (char *)buf_window_start(buffer), 649 buf_window_size(buffer)); 650 651 /*deallocate buffer*/ 652 buf_close(buffer); 653 654 /*return string*/ 655 return string; 656 } 657 } 658 659 static PyObject* 660 BitstreamReader_read_bytes(bitstream_BitstreamReader *self, 661 PyObject *args) 662 { 663 PyObject *byte_count; 664 665 if (!PyArg_ParseTuple(args, "O", &byte_count)) { 666 return NULL; 667 } 668 669 return brpy_read_bytes_obj(self->bitstream, byte_count); 670 } 671 672 static PyObject* 673 BitstreamReader_set_endianness(bitstream_BitstreamReader *self, 674 PyObject *args) 675 { 676 int little_endian; 677 678 if (!PyArg_ParseTuple(args, "i", &little_endian)) 679 return NULL; 680 681 switch (little_endian) { 682 case 0: 683 self->bitstream->set_endianness(self->bitstream, BS_BIG_ENDIAN); 684 Py_INCREF(Py_None); 685 return Py_None; 686 case 1: 687 self->bitstream->set_endianness(self->bitstream, BS_LITTLE_ENDIAN); 688 Py_INCREF(Py_None); 689 return Py_None; 690 default: 691 PyErr_SetString( 692 PyExc_ValueError, 693 "endianness must be 0 (big-endian) or 1 (little-endian)"); 694 return NULL; 695 } 696 } 697 698 static PyObject* 699 BitstreamReader_close(bitstream_BitstreamReader *self, PyObject *args) 700 { 701 self->bitstream->close_internal_stream(self->bitstream); 702 Py_INCREF(Py_None); 703 return Py_None; 704 } 705 706 static PyObject* 707 BitstreamReader_getpos(bitstream_BitstreamReader *self, PyObject *args) 708 { 709 return PyObject_CallFunction( 710 (PyObject*)&bitstream_BitstreamReaderPositionType, "O", self); 711 } 712 713 static PyObject* 714 BitstreamReader_setpos(bitstream_BitstreamReader *self, PyObject *args) 715 { 716 bitstream_BitstreamReaderPosition* pos_obj; 717 718 if (!PyArg_ParseTuple(args, "O!", 719 &bitstream_BitstreamReaderPositionType, 720 &pos_obj)) 721 return NULL; 722 723 /*ensure position has come from this reader*/ 724 if (pos_obj->pos->reader != self->bitstream) { 725 PyErr_SetString(PyExc_IOError, 726 "position is not from this BitstreamReader"); 727 return NULL; 728 } 729 730 if (!setjmp(*br_try(self->bitstream))) { 731 self->bitstream->setpos(self->bitstream, pos_obj->pos); 732 br_etry(self->bitstream); 733 734 Py_INCREF(Py_None); 735 return Py_None; 736 } else { 737 /*raise IOError if some problem occurs setting the position*/ 738 br_etry(self->bitstream); 739 740 PyErr_SetString(PyExc_IOError, "unable to set position"); 741 return NULL; 742 } 743 } 744 745 /*given a numeric object 746 extracts the highest possible long to "l" 747 and returns a new reference to a numeric object with that amount removed*/ 748 static PyObject* 749 extract_largest_long(PyObject *number, long *l) 750 { 751 PyObject *long_max = PyInt_FromLong(LONG_MAX); 752 753 if (PyObject_RichCompareBool(number, long_max, Py_GT)) { 754 PyObject *to_return = PyNumber_Subtract(number, long_max); 755 Py_DECREF(long_max); 756 *l = LONG_MAX; 757 return to_return; 758 } else { 759 Py_DECREF(long_max); 760 *l = PyInt_AsLong(number); 761 return PyNumber_Subtract(number, number); 762 } 763 } 764 765 /*given a numeric object 766 extracts the smallest possible long to "l" 767 and returns a new reference to a numeric object with that amount removed*/ 768 static PyObject* 769 extract_smallest_long(PyObject *number, long *l) 770 { 771 PyObject *long_min = PyInt_FromLong(LONG_MIN); 772 773 if (PyObject_RichCompareBool(number, long_min, Py_LT)) { 774 PyObject *to_return = PyNumber_Subtract(number, long_min); 775 Py_DECREF(long_min); 776 *l = LONG_MIN; 777 return to_return; 778 } else { 779 Py_DECREF(long_min); 780 *l = PyInt_AsLong(number); 781 return PyNumber_Subtract(number, number); 782 } 783 } 784 785 786 static PyObject* 787 BitstreamReader_seek(bitstream_BitstreamReader *self, PyObject *args) 788 { 789 BitstreamReader *stream = self->bitstream; 790 PyObject *initial_position; 791 PyObject *position; 792 PyObject *temp; 793 int whence = 0; 794 PyObject *zero; 795 long seek_position; 796 797 if (!PyArg_ParseTuple(args, "O|i", &initial_position, &whence)) { 798 return NULL; 799 } else if (!PyNumber_Check(initial_position)) { 800 PyErr_SetString(PyExc_TypeError, "position must be a numeric object"); 801 return NULL; 802 } 803 804 position = initial_position; 805 Py_INCREF(position); 806 zero = PyInt_FromLong(0); 807 808 switch (whence) { 809 case 0: /*SEEK_SET*/ 810 { 811 /*ensure position is non-negative*/ 812 if (PyObject_RichCompareBool(position, zero, Py_LT)) { 813 PyErr_SetString(PyExc_IOError, "invalid seek position"); 814 goto error; 815 } 816 817 /*perform best absolute seek to initial position*/ 818 temp = extract_largest_long(position, &seek_position); 819 Py_DECREF(position); 820 position = temp; 821 if (!setjmp(*br_try(stream))) { 822 stream->seek(stream, seek_position, BS_SEEK_SET); 823 br_etry(stream); 824 } else { 825 /*I/O error when seeking*/ 826 br_etry(stream); 827 PyErr_SetString(PyExc_IOError, "I/O error performing seek"); 828 goto error; 829 } 830 831 /*cover remaining distance with relative seeks*/ 832 while (PyObject_RichCompareBool(position, zero, Py_GT)) { 833 temp = extract_largest_long(position, &seek_position); 834 Py_DECREF(position); 835 position = temp; 836 if (!setjmp(*br_try(stream))) { 837 stream->seek(stream, seek_position, BS_SEEK_CUR); 838 br_etry(stream); 839 } else { 840 /*I/O error when seeking*/ 841 br_etry(stream); 842 PyErr_SetString(PyExc_IOError, "I/O error performing seek"); 843 goto error; 844 } 845 } 846 } 847 break; 848 case 1: /*SEEK_CUR*/ 849 { 850 if (PyObject_RichCompareBool(position, zero, Py_GT)) { 851 /*cover positive distance with relative seeks*/ 852 while (PyObject_RichCompareBool(position, zero, Py_GT)) { 853 temp = extract_largest_long(position, &seek_position); 854 Py_DECREF(position); 855 position = temp; 856 if (!setjmp(*br_try(stream))) { 857 stream->seek(stream, seek_position, BS_SEEK_CUR); 858 br_etry(stream); 859 } else { 860 br_etry(stream); 861 PyErr_SetString(PyExc_IOError, 862 "I/O error performing seek"); 863 goto error; 864 } 865 } 866 } else if (PyObject_RichCompareBool(position, zero, Py_LT)) { 867 /*cover negative distance with relative seeks*/ 868 while (PyObject_RichCompareBool(position, zero, Py_LT)) { 869 temp = extract_smallest_long(position, &seek_position); 870 Py_DECREF(position); 871 position = temp; 872 if (!setjmp(*br_try(stream))) { 873 stream->seek(stream, seek_position, BS_SEEK_CUR); 874 br_etry(stream); 875 } else { 876 br_etry(stream); 877 PyErr_SetString(PyExc_IOError, 878 "I/O error performing seek"); 879 goto error; 880 } 881 } 882 } 883 /*position is 0, so no need to move anywhere*/ 884 } 885 break; 886 case 2: /*SEEK_END*/ 887 { 888 /*ensure position is non-positive*/ 889 if (PyObject_RichCompareBool(position, zero, Py_GT)) { 890 PyErr_SetString(PyExc_IOError, "invalid seek position"); 891 goto error; 892 } 893 894 /*perform best absolute seek to initial position*/ 895 temp = extract_smallest_long(position, &seek_position); 896 Py_DECREF(position); 897 position = temp; 898 if (!setjmp(*br_try(stream))) { 899 stream->seek(stream, seek_position, BS_SEEK_END); 900 br_etry(stream); 901 } else { 902 /*I/O error when seeking*/ 903 br_etry(stream); 904 PyErr_SetString(PyExc_IOError, 905 "I/O error performing seek"); 906 goto error; 907 } 908 909 /*cover remaining distance with relative seeks*/ 910 while (PyObject_RichCompareBool(position, zero, Py_LT)) { 911 temp = extract_smallest_long(position, &seek_position); 912 Py_DECREF(position); 913 position = temp; 914 if (!setjmp(*br_try(stream))) { 915 stream->seek(stream, seek_position, BS_SEEK_CUR); 916 br_etry(stream); 917 } else { 918 /*I/O error when seeking*/ 919 br_etry(stream); 920 PyErr_SetString(PyExc_IOError, 921 "I/O error performing seek"); 922 goto error; 923 } 924 } 925 } 926 break; 927 default: 928 PyErr_SetString(PyExc_ValueError, "whence must be 0, 1 or 2"); 929 goto error; 930 } 931 932 Py_DECREF(position); 933 Py_DECREF(zero); 934 Py_INCREF(Py_None); 935 return Py_None; 936 error: 937 Py_DECREF(position); 938 Py_DECREF(zero); 939 return NULL; 940 } 941 942 static PyObject* 943 BitstreamReader_add_callback(bitstream_BitstreamReader *self, PyObject *args) 944 { 945 PyObject* callback; 946 947 if (!PyArg_ParseTuple(args, "O", &callback)) 948 return NULL; 949 950 if (!PyCallable_Check(callback)) { 951 PyErr_SetString(PyExc_TypeError, "callback must be callable"); 952 return NULL; 953 } 954 955 Py_INCREF(callback); 956 self->bitstream->add_callback(self->bitstream, 957 (bs_callback_f)BitstreamReader_callback, 958 callback); 959 960 Py_INCREF(Py_None); 961 return Py_None; 962 } 963 964 static PyObject* 965 BitstreamReader_pop_callback(bitstream_BitstreamReader *self, PyObject *args) 966 { 967 struct bs_callback callback; 968 PyObject* callback_obj; 969 970 if (self->bitstream->callbacks != NULL) { 971 self->bitstream->pop_callback(self->bitstream, &callback); 972 callback_obj = callback.data; 973 /*decref object from stack and then incref object for return 974 should have a net effect of noop*/ 975 return callback_obj; 976 } else { 977 PyErr_SetString(PyExc_IndexError, "no callbacks to pop"); 978 return NULL; 979 } 980 } 981 982 static PyObject* 983 BitstreamReader_call_callbacks(bitstream_BitstreamReader *self, PyObject *args) 984 { 985 uint8_t byte; 986 987 if (!PyArg_ParseTuple(args, "b", &byte)) 988 return NULL; 989 990 self->bitstream->call_callbacks(self->bitstream, byte); 991 992 Py_INCREF(Py_None); 993 return Py_None; 994 } 995 996 void 997 BitstreamReader_callback(uint8_t byte, PyObject *callback) 998 { 999 PyObject* result = PyObject_CallFunction(callback, "B", byte); 1000 1001 if (result != NULL) { 1002 Py_DECREF(result); 1003 } else { 1004 PyErr_PrintEx(0); 1005 } 1006 } 1007 1008 static PyObject* 1009 BitstreamReader_substream(bitstream_BitstreamReader *self, PyObject *args) 1010 { 1011 PyTypeObject *type = Py_TYPE(self); 1012 long int bytes; 1013 1014 if (!PyArg_ParseTuple(args, "l", &bytes)) { 1015 return NULL; 1016 } else if (bytes < 0) { 1017 PyErr_SetString(PyExc_ValueError, "byte count must be >= 0"); 1018 return NULL; 1019 } else if (bytes > UINT_MAX) { 1020 return PyErr_Format(PyExc_ValueError, 1021 "byte count must be <= %u", 1022 UINT_MAX); 1023 } 1024 1025 if (!setjmp(*br_try(self->bitstream))) { 1026 bitstream_BitstreamReader *obj; 1027 BitstreamReader *substream = 1028 self->bitstream->substream(self->bitstream, (unsigned)bytes); 1029 1030 br_etry(self->bitstream); 1031 1032 obj = (bitstream_BitstreamReader *)type->tp_alloc(type, 0); 1033 obj->bitstream = substream; 1034 return (PyObject *)obj; 1035 } else { 1036 br_etry(self->bitstream); 1037 /*read error occurred during substream_append*/ 1038 PyErr_SetString(PyExc_IOError, "I/O error creating substream"); 1039 return NULL; 1040 } 1041 } 1042 1043 static PyObject* 1044 BitstreamReader_parse(bitstream_BitstreamReader *self, PyObject *args) 1045 { 1046 char* format; 1047 1048 if (!PyArg_ParseTuple(args, "s", &format)) { 1049 return NULL; 1050 } else { 1051 PyObject *values = PyList_New(0); 1052 1053 if (!bitstream_parse(self->bitstream, 1054 format, 1055 values)) { 1056 return values; 1057 } else { 1058 Py_DECREF(values); 1059 return NULL; 1060 } 1061 } 1062 } 1063 1064 PyObject* 1065 BitstreamReader_new(PyTypeObject *type, 1066 PyObject *args, PyObject *kwds) 1067 { 1068 bitstream_BitstreamReader *self; 1069 1070 self = (bitstream_BitstreamReader *)type->tp_alloc(type, 0); 1071 1072 return (PyObject *)self; 1073 } 1074 1075 int 1076 BitstreamReader_init(bitstream_BitstreamReader *self, 1077 PyObject *args) 1078 { 1079 PyObject *file_obj; 1080 int little_endian; 1081 int buffer_size = 4096; 1082 1083 self->bitstream = NULL; 1084 1085 if (!PyArg_ParseTuple(args, "Oi|i", 1086 &file_obj, 1087 &little_endian, 1088 &buffer_size)) { 1089 return -1; 1090 } else if (buffer_size <= 0) { 1091 PyErr_SetString(PyExc_ValueError, "buffer_size must be > 0"); 1092 return -1; 1093 } 1094 1095 if (PyBytes_CheckExact(file_obj)) { 1096 /*dump contents of Python string into internal buffer*/ 1097 char *buffer; 1098 Py_ssize_t length; 1099 1100 if (PyBytes_AsStringAndSize(file_obj, &buffer, &length) == -1) { 1101 /*some error during string conversion*/ 1102 return -1; 1103 } 1104 1105 /*FIXME - this presumes buffer can holder more bytes than 1106 an unsigned int, which isn't the case yet*/ 1107 self->bitstream = br_open_buffer((uint8_t*)buffer, 1108 (unsigned)length, 1109 little_endian ? 1110 BS_LITTLE_ENDIAN : BS_BIG_ENDIAN); 1111 } else { 1112 /*store a reference to the Python object so that it doesn't decref 1113 (and close) the file out from under us*/ 1114 Py_INCREF(file_obj); 1115 1116 self->bitstream = br_open_external( 1117 file_obj, 1118 little_endian ? BS_LITTLE_ENDIAN : BS_BIG_ENDIAN, 1119 (unsigned)buffer_size, 1120 (ext_read_f)br_read_python, 1121 (ext_setpos_f)bs_setpos_python, 1122 (ext_getpos_f)bs_getpos_python, 1123 (ext_free_pos_f)bs_free_pos_python, 1124 (ext_seek_f)bs_fseek_python, 1125 (ext_close_f)bs_close_python, 1126 (ext_free_f)bs_free_python_decref); 1127 } 1128 1129 return 0; 1130 } 1131 1132 void 1133 BitstreamReader_dealloc(bitstream_BitstreamReader *self) 1134 { 1135 struct bs_callback *c_node; 1136 1137 if (self->bitstream != NULL) { 1138 /*DECREF all active callback data*/ 1139 for (c_node = self->bitstream->callbacks; 1140 c_node != NULL; 1141 c_node = c_node->next) { 1142 Py_DECREF(c_node->data); 1143 } 1144 1145 /*perform free() on rest of BitstreamReader*/ 1146 self->bitstream->free(self->bitstream); 1147 } 1148 1149 Py_TYPE(self)->tp_free((PyObject*)self); 1150 } 1151 1152 static PyObject* 1153 BitstreamReader_enter(bitstream_BitstreamReader *self, PyObject *args) 1154 { 1155 Py_INCREF(self); 1156 return (PyObject *)self; 1157 } 1158 1159 static PyObject* 1160 BitstreamReader_exit(bitstream_BitstreamReader *self, PyObject *args) 1161 { 1162 self->bitstream->close_internal_stream(self->bitstream); 1163 Py_INCREF(Py_None); 1164 return Py_None; 1165 } 1166 1167 /*this functions similarly to json_to_frequencies -> compile_huffman_table*/ 1168 int 1169 HuffmanTree_init(bitstream_HuffmanTree *self, PyObject *args) 1170 { 1171 PyObject* frequencies_list; 1172 PyObject* bits_list; 1173 PyObject* value_obj; 1174 long value_int_value; 1175 PyObject* bits_int; 1176 long bits_int_value; 1177 int little_endian; 1178 Py_ssize_t list_length; 1179 Py_ssize_t bits_length; 1180 Py_ssize_t i,o,j; 1181 struct huffman_frequency* frequencies = NULL; 1182 struct huffman_frequency frequency; 1183 1184 /*most of this stuff is for converting Python objects 1185 to plain integers for use by compile_huffman_table*/ 1186 1187 self->br_table = NULL; 1188 self->bw_table = NULL; 1189 1190 if (!PyArg_ParseTuple(args, "Oi", &frequencies_list, &little_endian)) 1191 return -1; 1192 1193 if ((list_length = PySequence_Length(frequencies_list)) == -1) { 1194 return -1; 1195 } 1196 if (list_length < 1) { 1197 PyErr_SetString(PyExc_ValueError, "frequencies cannot be empty"); 1198 return -1; 1199 } 1200 if (list_length % 2) { 1201 PyErr_SetString(PyExc_ValueError, 1202 "frequencies must have an even number of elements"); 1203 return -1; 1204 } 1205 1206 frequencies = malloc(sizeof(struct huffman_frequency) * (list_length / 2)); 1207 1208 for (i = o = 0; i < list_length; i += 2,o++) { 1209 frequency.bits = frequency.length = 0; 1210 bits_list = value_obj = bits_int = NULL; 1211 1212 if ((bits_list = PySequence_GetItem(frequencies_list, i)) == NULL) 1213 goto error; 1214 1215 if ((value_obj = PySequence_GetItem(frequencies_list, i + 1)) == NULL) 1216 goto error; 1217 1218 /*bits are always consumed in big-endian order*/ 1219 if ((bits_length = PySequence_Length(bits_list)) == -1) 1220 goto error; 1221 1222 for (j = 0; j < bits_length; j++) { 1223 bits_int = NULL; 1224 if ((bits_int = PySequence_GetItem(bits_list, j)) == NULL) 1225 goto error; 1226 if (((bits_int_value = PyInt_AsLong(bits_int)) == -1) && 1227 PyErr_Occurred()) 1228 goto error; 1229 1230 if ((bits_int_value != 0) && (bits_int_value != 1)) { 1231 PyErr_SetString(PyExc_ValueError, "bits must be 0 or 1"); 1232 goto error; 1233 } 1234 1235 frequency.bits = (unsigned int)((frequency.bits << 1) | 1236 bits_int_value); 1237 frequency.length++; 1238 1239 Py_DECREF(bits_int); 1240 bits_int = NULL; 1241 } 1242 1243 /*value must always be an integer*/ 1244 if (((value_int_value = PyInt_AsLong(value_obj)) == -1) && 1245 PyErr_Occurred()) 1246 goto error; 1247 1248 frequency.value = (int)value_int_value; 1249 1250 frequencies[o] = frequency; 1251 1252 Py_DECREF(bits_list); 1253 Py_DECREF(value_obj); 1254 bits_list = value_obj = NULL; 1255 } 1256 1257 switch (compile_br_huffman_table(&(self->br_table), 1258 frequencies, 1259 (unsigned int)(list_length / 2), 1260 little_endian ? 1261 BS_LITTLE_ENDIAN : BS_BIG_ENDIAN)) { 1262 case HUFFMAN_MISSING_LEAF: 1263 PyErr_SetString(PyExc_ValueError, "Huffman tree missing leaf"); 1264 goto error; 1265 case HUFFMAN_DUPLICATE_LEAF: 1266 PyErr_SetString(PyExc_ValueError, "Huffman tree has duplicate leaf"); 1267 goto error; 1268 case HUFFMAN_ORPHANED_LEAF: 1269 PyErr_SetString(PyExc_ValueError, "Huffman tree has orphaned leaf"); 1270 goto error; 1271 case HUFFMAN_EMPTY_TREE: 1272 PyErr_SetString(PyExc_ValueError, "Huffman tree is empty"); 1273 goto error; 1274 default: 1275 break; 1276 } 1277 1278 switch (compile_bw_huffman_table(&(self->bw_table), 1279 frequencies, 1280 (unsigned int)(list_length / 2), 1281 little_endian ? 1282 BS_LITTLE_ENDIAN : BS_BIG_ENDIAN)) { 1283 /*these shouldn't be triggered if compile_br_table succeeds*/ 1284 case HUFFMAN_MISSING_LEAF: 1285 PyErr_SetString(PyExc_ValueError, "Huffman tree missing leaf"); 1286 goto error; 1287 case HUFFMAN_DUPLICATE_LEAF: 1288 PyErr_SetString(PyExc_ValueError, "Huffman tree has duplicate leaf"); 1289 goto error; 1290 case HUFFMAN_ORPHANED_LEAF: 1291 PyErr_SetString(PyExc_ValueError, "Huffman tree has orphaned leaf"); 1292 goto error; 1293 case HUFFMAN_EMPTY_TREE: 1294 PyErr_SetString(PyExc_ValueError, "Huffman tree is empty"); 1295 goto error; 1296 default: 1297 break; 1298 } 1299 1300 free(frequencies); 1301 return 0; 1302 error: 1303 Py_XDECREF(bits_int); 1304 Py_XDECREF(bits_list); 1305 Py_XDECREF(value_obj); 1306 if (frequencies != NULL) 1307 free(frequencies); 1308 return -1; 1309 } 1310 1311 void 1312 HuffmanTree_dealloc(bitstream_HuffmanTree *self) 1313 { 1314 free(self->br_table); 1315 free(self->bw_table); 1316 1317 Py_TYPE(self)->tp_free((PyObject*)self); 1318 } 1319 1320 static PyObject* 1321 HuffmanTree_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 1322 { 1323 bitstream_HuffmanTree *self; 1324 1325 self = (bitstream_HuffmanTree *)type->tp_alloc(type, 0); 1326 1327 return (PyObject *)self; 1328 } 1329 1330 static PyObject* 1331 BitstreamReaderPosition_new(PyTypeObject *type, PyObject *args, 1332 PyObject *kwds) 1333 { 1334 bitstream_BitstreamReaderPosition *self; 1335 1336 self = (bitstream_BitstreamReaderPosition *)type->tp_alloc(type, 0); 1337 1338 return (PyObject *)self; 1339 } 1340 1341 int 1342 BitstreamReaderPosition_init(bitstream_BitstreamReaderPosition *self, 1343 PyObject *args) 1344 { 1345 bitstream_BitstreamReader *reader_obj; 1346 BitstreamReader *reader; 1347 self->pos = NULL; 1348 1349 if (PyArg_ParseTuple(args, "O!", 1350 &bitstream_BitstreamReaderType, 1351 &reader_obj)) { 1352 reader = reader_obj->bitstream; 1353 } else { 1354 return -1; 1355 } 1356 1357 /*get position from reader*/ 1358 if (!setjmp(*br_try(reader))) { 1359 self->pos = reader->getpos(reader); 1360 br_etry(reader); 1361 return 0; 1362 } else { 1363 /*some I/O error occurred getting position*/ 1364 br_etry(reader); 1365 PyErr_SetString(PyExc_IOError, "I/O error getting position"); 1366 return -1; 1367 } 1368 } 1369 1370 void 1371 BitstreamReaderPosition_dealloc(bitstream_BitstreamReaderPosition *self) 1372 { 1373 /*since the position contains a copy of the "free" function 1374 needed to free the object returned by getpos, 1375 this position object can be safely freed after its parent reader*/ 1376 if (self->pos) { 1377 self->pos->del(self->pos); 1378 } 1379 1380 Py_TYPE(self)->tp_free((PyObject*)self); 1381 } 1382 1383 int 1384 BitstreamWriter_init(bitstream_BitstreamWriter *self, PyObject *args) 1385 { 1386 PyObject *file_obj; 1387 int little_endian; 1388 int buffer_size = 4096; 1389 1390 self->bitstream = NULL; 1391 1392 if (!PyArg_ParseTuple(args, "Oi|i", &file_obj, &little_endian, 1393 &buffer_size)) { 1394 return -1; 1395 } else if (buffer_size <= 0) { 1396 PyErr_SetString(PyExc_ValueError, "buffer_size must be > 0"); 1397 return -1; 1398 } 1399 1400 /*store a reference to the Python object so that it doesn't decref 1401 (and close) the file out from under us*/ 1402 Py_INCREF(file_obj); 1403 1404 self->bitstream = bw_open_external( 1405 file_obj, 1406 little_endian ? BS_LITTLE_ENDIAN : BS_BIG_ENDIAN, 1407 (unsigned)buffer_size, 1408 (ext_write_f)bw_write_python, 1409 (ext_setpos_f)bs_setpos_python, 1410 (ext_getpos_f)bs_getpos_python, 1411 (ext_free_pos_f)bs_free_pos_python, 1412 (ext_flush_f)bw_flush_python, 1413 (ext_close_f)bs_close_python, 1414 (ext_free_f)bs_free_python_decref); 1415 1416 return 0; 1417 } 1418 1419 static PyObject* 1420 bwpy_min_unsigned(unsigned bits) 1421 { 1422 return PyInt_FromLong(0); 1423 } 1424 1425 static PyObject* 1426 bwpy_max_unsigned(unsigned bits) 1427 { 1428 /*(2 ^ bits) - 1*/ 1429 PyObject *one; 1430 PyObject *bits_obj; 1431 PyObject *shifted; 1432 PyObject *value; 1433 1434 one = PyInt_FromLong(1); 1435 bits_obj = PyInt_FromLong(bits); 1436 shifted = PyNumber_Lshift(one, bits_obj); 1437 Py_DECREF(bits_obj); 1438 if (shifted == NULL) { 1439 Py_DECREF(one); 1440 return NULL; 1441 } 1442 value = PyNumber_Subtract(shifted, one); 1443 Py_DECREF(shifted); 1444 Py_DECREF(one); 1445 return value; 1446 } 1447 1448 static PyObject* 1449 bwpy_min_signed(unsigned bits) 1450 { 1451 /*-(2 ^ (bits - 1))*/ 1452 PyObject *one; 1453 PyObject *bits_obj; 1454 PyObject *shifted; 1455 PyObject *value; 1456 1457 one = PyInt_FromLong(1); 1458 bits_obj = PyInt_FromLong(bits - 1); 1459 shifted = PyNumber_Lshift(one, bits_obj); 1460 Py_DECREF(one); 1461 Py_DECREF(bits_obj); 1462 if (shifted == NULL) 1463 return NULL; 1464 value = PyNumber_Negative(shifted); 1465 Py_DECREF(shifted); 1466 return value; 1467 } 1468 1469 static PyObject* 1470 bwpy_max_signed(unsigned bits) 1471 { 1472 /*(2 ^ (bits - 1)) - 1*/ 1473 return bwpy_max_unsigned(bits - 1); 1474 } 1475 1476 static int 1477 bwpy_in_range(PyObject *min_value, PyObject *value, PyObject *max_value) 1478 { 1479 const int cmp_min = PyObject_RichCompareBool(min_value, value, Py_LE); 1480 if (cmp_min == -1) { 1481 return -1; 1482 } else { 1483 const int cmp_max = PyObject_RichCompareBool(value, max_value, Py_LE); 1484 if (cmp_max == -1) { 1485 return -1; 1486 } else { 1487 return (cmp_min == 1) && (cmp_max == 1); 1488 } 1489 } 1490 } 1491 1492 #define FUNC_VALIDATE_RANGE(FUNC_NAME, MIN_FUNC, MAX_FUNC, TYPE_STR) \ 1493 static int \ 1494 FUNC_NAME(unsigned bits, PyObject *value) { \ 1495 PyObject *min_value; \ 1496 PyObject *max_value; \ 1497 int comparison; \ 1498 \ 1499 if (!PyNumber_Check(value)) { \ 1500 PyErr_SetString(PyExc_TypeError, "value is not a number"); \ 1501 return 0; \ 1502 } \ 1503 \ 1504 min_value = MIN_FUNC(bits); \ 1505 max_value = MAX_FUNC(bits); \ 1506 \ 1507 if (min_value == NULL) { \ 1508 Py_XDECREF(max_value); \ 1509 return 0; \ 1510 } else if (max_value == NULL) { \ 1511 Py_DECREF(min_value); \ 1512 return 0; \ 1513 } \ 1514 \ 1515 comparison = bwpy_in_range(min_value, value, max_value); \ 1516 Py_DECREF(min_value); \ 1517 Py_DECREF(max_value); \ 1518 \ 1519 switch (comparison) { \ 1520 case 1: \ 1521 return 1; \ 1522 case 0: \ 1523 PyErr_Format(PyExc_ValueError, \ 1524 "value does not fit in %u " TYPE_STR " %s", \ 1525 bits, \ 1526 bits != 1 ? "bits" : "bit"); \ 1527 return 0; \ 1528 default: \ 1529 return 0; \ 1530 } \ 1531 } 1532 FUNC_VALIDATE_RANGE(bw_validate_unsigned_range, 1533 bwpy_min_unsigned, 1534 bwpy_max_unsigned, 1535 "unsigned") 1536 FUNC_VALIDATE_RANGE(bw_validate_signed_range, 1537 bwpy_min_signed, 1538 bwpy_max_signed, 1539 "signed") 1540 1541 static int 1542 bwpy_write_unsigned(BitstreamWriter *bw, unsigned bits, PyObject *value) 1543 { 1544 if (bits == 0) { 1545 /*do nothing*/ 1546 return 0; 1547 } 1548 if (!bw_validate_unsigned_range(bits, value)) { 1549 return 1; 1550 } 1551 1552 if (!setjmp(*bw_try(bw))) { 1553 if (bits <= (sizeof(unsigned int) * 8)) { 1554 /*value should fit in an unsigned int*/ 1555 PyObject *long_obj = PyNumber_Long(value); 1556 if (long_obj) { 1557 const unsigned long u_value = PyLong_AsUnsignedLong(long_obj); 1558 Py_DECREF(long_obj); 1559 bw->write(bw, bits, (unsigned)u_value); 1560 bw_etry(bw); 1561 return 0; 1562 } else { 1563 bw_etry(bw); 1564 return 1; 1565 } 1566 } else if (bits <= (sizeof(uint64_t) * 8)) { 1567 /*value should fit in a uint64_t*/ 1568 PyObject *long_obj = PyNumber_Long(value); 1569 if (long_obj) { 1570 const unsigned long long u_value = 1571 PyLong_AsUnsignedLongLong(long_obj); 1572 Py_DECREF(long_obj); 1573 bw->write_64(bw, bits, (uint64_t)u_value); 1574 bw_etry(bw); 1575 return 0; 1576 } else { 1577 bw_etry(bw); 1578 return 1; 1579 } 1580 } else { 1581 /*finally, try write_bigint*/ 1582 1583 /*serialize long to string*/ 1584 PyObject *string_obj = PyNumber_ToBase(value, 10); 1585 1586 /*convert to mpz_t*/ 1587 mpz_t value; 1588 #if PY_MAJOR_VERSION >= 3 1589 /*I hope this is NULL-terminated 1590 since the documentation doesn't say*/ 1591 mpz_init_set_str(value, PyUnicode_AsUTF8(string_obj), 10); 1592 #else 1593 mpz_init_set_str(value, PyString_AsString(string_obj), 10); 1594 #endif 1595 Py_DECREF(string_obj); 1596 1597 /*perform write*/ 1598 if (!setjmp(*bw_try(bw))) { 1599 bw->write_bigint(bw, bits, value); 1600 bw_etry(bw); 1601 mpz_clear(value); 1602 } else { 1603 /*ensure result gets cleared before re-raising error*/ 1604 bw_etry(bw); 1605 mpz_clear(value); 1606 bw_abort(bw); 1607 } 1608 1609 /*return sucess*/ 1610 bw_etry(bw); 1611 return 0; 1612 } 1613 } else { 1614 bw_etry(bw); 1615 PyErr_SetString(PyExc_IOError, "I/O error writing stream"); 1616 return 1; 1617 } 1618 } 1619 1620 static int 1621 bwpy_write_signed(BitstreamWriter *bw, unsigned bits, PyObject *value) 1622 { 1623 /*ensure value fits in range*/ 1624 if (!bw_validate_signed_range(bits, value)) 1625 return 1; 1626 1627 if (!setjmp(*bw_try(bw))) { 1628 if (bits <= (sizeof(int) * 8)) { 1629 /*value should fit in a signed int*/ 1630 const long i_value = PyInt_AsLong(value); 1631 bw->write_signed(bw, bits, (int)i_value); 1632 bw_etry(bw); 1633 return 0; 1634 } else if (bits <= (sizeof(int64_t) * 8)) { 1635 /*value should fit in an int64_t*/ 1636 const long long i_value = PyLong_AsLongLong(value); 1637 bw->write_signed_64(bw, bits, (int64_t)i_value); 1638 bw_etry(bw); 1639 return 0; 1640 } else { 1641 /*finally, try write_signed_bigint*/ 1642 1643 /*serialize long to string*/ 1644 PyObject *string_obj = PyNumber_ToBase(value, 10); 1645 1646 /*convert to mpz_t*/ 1647 mpz_t value; 1648 #if PY_MAJOR_VERSION >= 3 1649 /*I hope this is NULL-terminated 1650 since the documentation doesn't say*/ 1651 mpz_init_set_str(value, PyUnicode_AsUTF8(string_obj), 10); 1652 #else 1653 mpz_init_set_str(value, PyString_AsString(string_obj), 10); 1654 #endif 1655 Py_DECREF(string_obj); 1656 1657 /*perform write*/ 1658 if (!setjmp(*bw_try(bw))) { 1659 bw->write_signed_bigint(bw, bits, value); 1660 bw_etry(bw); 1661 mpz_clear(value); 1662 } else { 1663 /*ensure result gets cleared before re-raising error*/ 1664 bw_etry(bw); 1665 mpz_clear(value); 1666 bw_abort(bw); 1667 } 1668 1669 /*return sucess*/ 1670 bw_etry(bw); 1671 return 0; 1672 } 1673 } else { 1674 bw_etry(bw); 1675 PyErr_SetString(PyExc_IOError, "I/O error writing stream"); 1676 return 1; 1677 } 1678 } 1679 1680 void 1681 BitstreamWriter_dealloc(bitstream_BitstreamWriter *self) 1682 { 1683 if (self->bitstream != NULL) { 1684 /*if stream is already closed, 1685 flush will do nothing*/ 1686 if (!setjmp(*bw_try(self->bitstream))) { 1687 self->bitstream->flush(self->bitstream); 1688 bw_etry(self->bitstream); 1689 } else { 1690 /*trying to dealloc BitstreamWriter after stream is closed 1691 is likely to be a problem*/ 1692 bw_etry(self->bitstream); 1693 fprintf(stderr, 1694 "*** Warning: Error occurred trying " 1695 "to flush stream during dealloc\n"); 1696 } 1697 self->bitstream->free(self->bitstream); 1698 } 1699 1700 Py_TYPE(self)->tp_free((PyObject*)self); 1701 } 1702 1703 static PyObject* 1704 BitstreamWriter_new(PyTypeObject *type, PyObject *args, 1705 PyObject *kwds) 1706 { 1707 bitstream_BitstreamWriter *self; 1708 1709 self = (bitstream_BitstreamWriter *)type->tp_alloc(type, 0); 1710 1711 return (PyObject *)self; 1712 } 1713 1714 static PyObject* 1715 BitstreamWriter_write(bitstream_BitstreamWriter *self, PyObject *args) 1716 { 1717 int count; 1718 PyObject *value; 1719 1720 if (!PyArg_ParseTuple(args, "iO", &count, &value)) { 1721 return NULL; 1722 } else if (count < 0) { 1723 PyErr_SetString(PyExc_ValueError, "count must be >= 0"); 1724 return NULL; 1725 } 1726 1727 if (!bw_validate_unsigned_range((unsigned)count, value)) { 1728 return NULL; 1729 } else if (bwpy_write_unsigned(self->bitstream, (unsigned)count, value)) { 1730 return NULL; 1731 } else { 1732 Py_INCREF(Py_None); 1733 return Py_None; 1734 } 1735 } 1736 1737 static PyObject* 1738 BitstreamWriter_write_signed(bitstream_BitstreamWriter *self, PyObject *args) 1739 { 1740 int count; 1741 PyObject *value; 1742 1743 if (!PyArg_ParseTuple(args, "iO", &count, &value)) { 1744 return NULL; 1745 } else if (count <= 0) { 1746 PyErr_SetString(PyExc_ValueError, "count must be > 0"); 1747 return NULL; 1748 } 1749 1750 if (bwpy_write_signed(self->bitstream, (unsigned)count, value)) { 1751 return NULL; 1752 } else { 1753 Py_INCREF(Py_None); 1754 return Py_None; 1755 } 1756 } 1757 1758 static PyObject* 1759 BitstreamWriter_unary(bitstream_BitstreamWriter *self, PyObject *args) 1760 { 1761 int stop_bit; 1762 unsigned int value; 1763 1764 if (!PyArg_ParseTuple(args, "iI", &stop_bit, &value)) 1765 return NULL; 1766 1767 if ((stop_bit != 0) && (stop_bit != 1)) { 1768 PyErr_SetString(PyExc_ValueError, "stop bit must be 0 or 1"); 1769 return NULL; 1770 } 1771 1772 if (!setjmp(*bw_try(self->bitstream))) { 1773 self->bitstream->write_unary(self->bitstream, stop_bit, value); 1774 bw_etry(self->bitstream); 1775 Py_INCREF(Py_None); 1776 return Py_None; 1777 } else { 1778 bw_etry(self->bitstream); 1779 PyErr_SetString(PyExc_IOError, "I/O error writing stream"); 1780 return NULL; 1781 } 1782 } 1783 1784 static PyObject* 1785 BitstreamWriter_write_huffman_code(bitstream_BitstreamWriter *self, 1786 PyObject *args) 1787 { 1788 bitstream_HuffmanTree* huffman_tree; 1789 int value; 1790 BitstreamWriter* writer = self->bitstream; 1791 1792 if (!PyArg_ParseTuple(args, "O!i", 1793 &bitstream_HuffmanTreeType, 1794 &huffman_tree, 1795 &value)) 1796 return NULL; 1797 1798 if (!setjmp(*bw_try(writer))) { 1799 const int result = writer->write_huffman_code( 1800 writer, huffman_tree->bw_table, value); 1801 1802 bw_etry(writer); 1803 1804 if (result) { 1805 PyErr_SetString(PyExc_ValueError, "invalid HuffmanTree value"); 1806 return NULL; 1807 } else { 1808 Py_INCREF(Py_None); 1809 return Py_None; 1810 } 1811 } else { 1812 bw_etry(writer); 1813 PyErr_SetString(PyExc_IOError, "I/O error writing stream"); 1814 return NULL; 1815 } 1816 } 1817 1818 static PyObject* 1819 BitstreamWriter_byte_align(bitstream_BitstreamWriter *self, PyObject *args) 1820 { 1821 if (!setjmp(*bw_try(self->bitstream))) { 1822 self->bitstream->byte_align(self->bitstream); 1823 bw_etry(self->bitstream); 1824 Py_INCREF(Py_None); 1825 return Py_None; 1826 } else { 1827 bw_etry(self->bitstream); 1828 PyErr_SetString(PyExc_IOError, "I/O error writing stream"); 1829 return NULL; 1830 } 1831 } 1832 1833 static PyObject* 1834 BitstreamWriter_byte_aligned(bitstream_BitstreamWriter *self, PyObject *args) 1835 { 1836 return PyBool_FromLong(self->bitstream->byte_aligned(self->bitstream)); 1837 } 1838 1839 static PyObject* 1840 BitstreamWriter_write_bytes(bitstream_BitstreamWriter *self, 1841 PyObject *args) 1842 { 1843 const char* bytes; 1844 #ifdef PY_SSIZE_T_CLEAN 1845 Py_ssize_t bytes_len; 1846 #else 1847 int bytes_len; 1848 #endif 1849 1850 if (!PyArg_ParseTuple(args, "s#", &bytes, &bytes_len)) 1851 return NULL; 1852 1853 if (!setjmp(*bw_try(self->bitstream))) { 1854 self->bitstream->write_bytes(self->bitstream, 1855 (uint8_t*)bytes, bytes_len); 1856 bw_etry(self->bitstream); 1857 Py_INCREF(Py_None); 1858 return Py_None; 1859 } else { 1860 bw_etry(self->bitstream); 1861 PyErr_SetString(PyExc_IOError, "I/O error writing stream"); 1862 return NULL; 1863 } 1864 } 1865 1866 static PyObject* 1867 BitstreamWriter_build(bitstream_BitstreamWriter *self, PyObject *args) 1868 { 1869 char* format; 1870 PyObject *values; 1871 PyObject *iterator; 1872 1873 if (!PyArg_ParseTuple(args, "sO", &format, &values)) { 1874 return NULL; 1875 } else if ((iterator = PyObject_GetIter(values)) == NULL) { 1876 return NULL; 1877 } else if (bitstream_build(self->bitstream, 1878 format, 1879 iterator)) { 1880 Py_DECREF(iterator); 1881 return NULL; 1882 } else { 1883 Py_DECREF(iterator); 1884 Py_INCREF(Py_None); 1885 return Py_None; 1886 } 1887 } 1888 1889 static PyObject* 1890 BitstreamWriter_flush(bitstream_BitstreamWriter *self, PyObject *args) 1891 { 1892 if (!setjmp(*bw_try(self->bitstream))) { 1893 self->bitstream->flush(self->bitstream); 1894 bw_etry(self->bitstream); 1895 Py_INCREF(Py_None); 1896 return Py_None; 1897 } else { 1898 bw_etry(self->bitstream); 1899 PyErr_SetString(PyExc_IOError, "I/O error writing stream"); 1900 return NULL; 1901 } 1902 } 1903 1904 static PyObject* 1905 BitstreamWriter_set_endianness(bitstream_BitstreamWriter *self, 1906 PyObject *args) 1907 { 1908 int little_endian; 1909 1910 if (!PyArg_ParseTuple(args, "i", &little_endian)) 1911 return NULL; 1912 1913 switch (little_endian) { 1914 case 0: 1915 self->bitstream->set_endianness(self->bitstream, BS_BIG_ENDIAN); 1916 Py_INCREF(Py_None); 1917 return Py_None; 1918 case 1: 1919 self->bitstream->set_endianness(self->bitstream, BS_LITTLE_ENDIAN); 1920 Py_INCREF(Py_None); 1921 return Py_None; 1922 default: 1923 PyErr_SetString( 1924 PyExc_ValueError, 1925 "endianness must be 0 (big-endian) or 1 (little-endian)"); 1926 return NULL; 1927 } 1928 } 1929 1930 static PyObject* 1931 BitstreamWriter_add_callback(bitstream_BitstreamWriter *self, 1932 PyObject *args) 1933 { 1934 PyObject* callback; 1935 1936 if (!PyArg_ParseTuple(args, "O", &callback)) 1937 return NULL; 1938 1939 if (!PyCallable_Check(callback)) { 1940 PyErr_SetString(PyExc_TypeError, "callback must be callable"); 1941 return NULL; 1942 } 1943 1944 Py_INCREF(callback); 1945 self->bitstream->add_callback(self->bitstream, 1946 (bs_callback_f)BitstreamWriter_callback, 1947 callback); 1948 1949 Py_INCREF(Py_None); 1950 return Py_None; 1951 } 1952 1953 static PyObject* 1954 BitstreamWriter_pop_callback(bitstream_BitstreamWriter *self, 1955 PyObject *args) 1956 { 1957 struct bs_callback callback; 1958 PyObject* callback_obj; 1959 1960 if (self->bitstream->callbacks != NULL) { 1961 self->bitstream->pop_callback(self->bitstream, &callback); 1962 callback_obj = callback.data; 1963 /*decref object from stack and then incref object for return 1964 should have a net effect of noop*/ 1965 return callback_obj; 1966 } else { 1967 PyErr_SetString(PyExc_IndexError, "no callbacks to pop"); 1968 return NULL; 1969 } 1970 } 1971 1972 static PyObject* 1973 BitstreamWriter_call_callbacks(bitstream_BitstreamWriter *self, 1974 PyObject *args) 1975 { 1976 uint8_t byte; 1977 1978 if (!PyArg_ParseTuple(args, "b", &byte)) 1979 return NULL; 1980 1981 self->bitstream->call_callbacks(self->bitstream, byte); 1982 1983 Py_INCREF(Py_None); 1984 return Py_None; 1985 } 1986 1987 static PyObject* 1988 BitstreamWriter_getpos(bitstream_BitstreamWriter *self, 1989 PyObject *args) 1990 { 1991 return PyObject_CallFunction( 1992 (PyObject*)&bitstream_BitstreamWriterPositionType, "O", self); 1993 } 1994 1995 static PyObject* 1996 BitstreamWriter_setpos(bitstream_BitstreamWriter *self, 1997 PyObject *args) 1998 { 1999 bitstream_BitstreamWriterPosition* pos_obj; 2000 2001 if (!PyArg_ParseTuple(args, "O!", 2002 &bitstream_BitstreamWriterPositionType, 2003 &pos_obj)) 2004 return NULL; 2005 2006 /*ensure position has come from this reader*/ 2007 if (pos_obj->pos->writer != self->bitstream) { 2008 PyErr_SetString(PyExc_IOError, 2009 "position is not from this BitstreamWriter"); 2010 return NULL; 2011 } 2012 2013 /*ensure stream is byte-aligned before setting position*/ 2014 if (!self->bitstream->byte_aligned(self->bitstream)) { 2015 PyErr_SetString(PyExc_IOError, "stream must be byte-aligned"); 2016 return NULL; 2017 } 2018 2019 if (!setjmp(*bw_try(self->bitstream))) { 2020 self->bitstream->setpos(self->bitstream, pos_obj->pos); 2021 bw_etry(self->bitstream); 2022 2023 Py_INCREF(Py_None); 2024 return Py_None; 2025 } else { 2026 /*raise IOError if some problem occurs setting the position*/ 2027 bw_etry(self->bitstream); 2028 2029 PyErr_SetString(PyExc_IOError, "unable to set position"); 2030 return NULL; 2031 } 2032 } 2033 2034 static PyObject* 2035 BitstreamWriter_close(bitstream_BitstreamWriter *self, PyObject *args) 2036 { 2037 self->bitstream->close_internal_stream(self->bitstream); 2038 Py_INCREF(Py_None); 2039 return Py_None; 2040 } 2041 2042 static PyObject* 2043 BitstreamWriter_enter(bitstream_BitstreamWriter *self, PyObject *args) 2044 { 2045 Py_INCREF(self); 2046 return (PyObject *)self; 2047 } 2048 2049 static PyObject* 2050 BitstreamWriter_exit(bitstream_BitstreamWriter *self, PyObject *args) 2051 { 2052 PyObject *exc_type; 2053 PyObject *exc_value; 2054 PyObject *traceback; 2055 2056 if (!PyArg_ParseTuple(args, "OOO", &exc_type, &exc_value, &traceback)) 2057 return NULL; 2058 2059 if ((exc_type == Py_None) && 2060 (exc_value == Py_None) && 2061 (traceback == Py_None)) { 2062 /*writer exited normally, so perform flush*/ 2063 if (!setjmp(*bw_try(self->bitstream))) { 2064 self->bitstream->flush(self->bitstream); 2065 } 2066 /*eat any error rather than propogate it with an exception*/ 2067 bw_etry(self->bitstream); 2068 } 2069 2070 /*close internal stream*/ 2071 self->bitstream->close_internal_stream(self->bitstream); 2072 2073 Py_INCREF(Py_None); 2074 return Py_None; 2075 } 2076 2077 static PyObject* 2078 BitstreamRecorder_write(bitstream_BitstreamRecorder *self, 2079 PyObject *args) 2080 { 2081 int count; 2082 PyObject *value; 2083 2084 if (!PyArg_ParseTuple(args, "iO", &count, &value)) { 2085 return NULL; 2086 } else if (count < 0) { 2087 PyErr_SetString(PyExc_ValueError, "count must be >= 0"); 2088 return NULL; 2089 } 2090 2091 if (!bw_validate_unsigned_range((unsigned)count, value)) { 2092 return NULL; 2093 } else if (bwpy_write_unsigned((BitstreamWriter*)self->bitstream, 2094 (unsigned)count, 2095 value)) { 2096 return NULL; 2097 } else { 2098 Py_INCREF(Py_None); 2099 return Py_None; 2100 } 2101 } 2102 2103 static PyObject* 2104 BitstreamRecorder_write_signed(bitstream_BitstreamRecorder *self, 2105 PyObject *args) 2106 { 2107 int count; 2108 PyObject *value; 2109 2110 if (!PyArg_ParseTuple(args, "iO", &count, &value)) { 2111 return NULL; 2112 } else if (count <= 0) { 2113 PyErr_SetString(PyExc_ValueError, "count must be > 0"); 2114 return NULL; 2115 } 2116 2117 2118 if (bwpy_write_signed((BitstreamWriter*)self->bitstream, 2119 (unsigned)count, 2120 value)) { 2121 return NULL; 2122 } else { 2123 Py_INCREF(Py_None); 2124 return Py_None; 2125 } 2126 } 2127 2128 static PyObject* 2129 BitstreamRecorder_unary(bitstream_BitstreamRecorder *self, 2130 PyObject *args) 2131 { 2132 BitstreamWriter* writer = (BitstreamWriter*)self->bitstream; 2133 int stop_bit; 2134 unsigned int value; 2135 2136 if (!PyArg_ParseTuple(args, "iI", &stop_bit, &value)) 2137 return NULL; 2138 2139 if ((stop_bit != 0) && (stop_bit != 1)) { 2140 PyErr_SetString(PyExc_ValueError, "stop bit must be 0 or 1"); 2141 return NULL; 2142 } 2143 2144 /*recorders can fail to write if the stream is closed*/ 2145 if (!setjmp(*bw_try(writer))) { 2146 writer->write_unary(writer, stop_bit, value); 2147 bw_etry(writer); 2148 Py_INCREF(Py_None); 2149 return Py_None; 2150 } else { 2151 bw_etry(writer); 2152 PyErr_SetString(PyExc_IOError, "I/O error writing stream"); 2153 return NULL; 2154 } 2155 } 2156 2157 static PyObject* 2158 BitstreamRecorder_write_huffman_code(bitstream_BitstreamRecorder *self, 2159 PyObject *args) 2160 { 2161 BitstreamWriter* writer = (BitstreamWriter*)self->bitstream; 2162 bitstream_HuffmanTree* huffman_tree; 2163 int value; 2164 2165 if (!PyArg_ParseTuple(args, "O!i", 2166 &bitstream_HuffmanTreeType, 2167 &huffman_tree, 2168 &value)) 2169 return NULL; 2170 2171 /*recorders can fail to write if the stream is closed*/ 2172 if (!setjmp(*bw_try(writer))) { 2173 const int result = writer->write_huffman_code( 2174 writer, huffman_tree->bw_table, value); 2175 2176 bw_etry(writer); 2177 2178 if (result) { 2179 PyErr_SetString(PyExc_ValueError, "invalid HuffmanTree value"); 2180 return NULL; 2181 } else { 2182 Py_INCREF(Py_None); 2183 return Py_None; 2184 } 2185 } else { 2186 bw_etry(writer); 2187 PyErr_SetString(PyExc_IOError, "I/O error writing stream"); 2188 return NULL; 2189 } 2190 } 2191 2192 static PyObject* 2193 BitstreamRecorder_byte_align(bitstream_BitstreamRecorder *self, 2194 PyObject *args) 2195 { 2196 BitstreamWriter* writer = (BitstreamWriter*)self->bitstream; 2197 2198 /*recorders can fail to write if the stream is closed*/ 2199 if (!setjmp(*bw_try(writer))) { 2200 writer->byte_align(writer); 2201 bw_etry(writer); 2202 Py_INCREF(Py_None); 2203 return Py_None; 2204 } else { 2205 bw_etry(writer); 2206 PyErr_SetString(PyExc_IOError, "I/O error writing stream"); 2207 return NULL; 2208 } 2209 } 2210 2211 static PyObject* 2212 BitstreamRecorder_byte_aligned(bitstream_BitstreamRecorder *self, 2213 PyObject *args) 2214 { 2215 return PyBool_FromLong( 2216 self->bitstream->byte_aligned((BitstreamWriter*)self->bitstream)); 2217 } 2218 2219 static PyObject* 2220 BitstreamRecorder_write_bytes(bitstream_BitstreamRecorder *self, 2221 PyObject *args) 2222 { 2223 BitstreamWriter* writer = (BitstreamWriter*)self->bitstream; 2224 const char* bytes; 2225 #ifdef PY_SSIZE_T_CLEAN 2226 Py_ssize_t bytes_len; 2227 #else 2228 int bytes_len; 2229 #endif 2230 2231 if (!PyArg_ParseTuple(args, "s#", &bytes, &bytes_len)) 2232 return NULL; 2233 2234 /*writers can fail to write if the stream is closed*/ 2235 if (!setjmp(*bw_try(writer))) { 2236 writer->write_bytes(writer, (uint8_t*)bytes, bytes_len); 2237 bw_etry(writer); 2238 Py_INCREF(Py_None); 2239 return Py_None; 2240 } else { 2241 bw_etry(writer); 2242 PyErr_SetString(PyExc_IOError, "I/O error writing stream"); 2243 return NULL; 2244 } 2245 } 2246 2247 static PyObject* 2248 BitstreamRecorder_build(bitstream_BitstreamRecorder *self, 2249 PyObject *args) 2250 { 2251 char* format; 2252 PyObject *values; 2253 PyObject *iterator; 2254 2255 if (!PyArg_ParseTuple(args, "sO", &format, &values)) { 2256 return NULL; 2257 } else if ((iterator = PyObject_GetIter(values)) == NULL) { 2258 return NULL; 2259 } else if (bitstream_build((BitstreamWriter*)self->bitstream, 2260 format, 2261 iterator)) { 2262 Py_DECREF(iterator); 2263 return NULL; 2264 } else { 2265 Py_DECREF(iterator); 2266 Py_INCREF(Py_None); 2267 return Py_None; 2268 } 2269 } 2270 2271 static PyObject* 2272 BitstreamRecorder_flush(bitstream_BitstreamRecorder *self, PyObject *args) 2273 { 2274 BitstreamWriter* writer = (BitstreamWriter*)self->bitstream; 2275 /*flush may fail if stream is closed*/ 2276 if (!setjmp(*bw_try(writer))) { 2277 writer->flush(writer); 2278 bw_etry(writer); 2279 Py_INCREF(Py_None); 2280 return Py_None; 2281 } else { 2282 bw_etry(writer); 2283 PyErr_SetString(PyExc_IOError, "I/O error writing stream"); 2284 return NULL; 2285 } 2286 } 2287 2288 static PyObject* 2289 BitstreamRecorder_set_endianness(bitstream_BitstreamRecorder *self, 2290 PyObject *args) 2291 { 2292 BitstreamWriter* writer = (BitstreamWriter*)self->bitstream; 2293 int little_endian; 2294 2295 if (!PyArg_ParseTuple(args, "i", &little_endian)) 2296 return NULL; 2297 2298 switch (little_endian) { 2299 case 0: 2300 writer->set_endianness(writer, BS_BIG_ENDIAN); 2301 Py_INCREF(Py_None); 2302 return Py_None; 2303 case 1: 2304 writer->set_endianness(writer, BS_LITTLE_ENDIAN); 2305 Py_INCREF(Py_None); 2306 return Py_None; 2307 default: 2308 PyErr_SetString( 2309 PyExc_ValueError, 2310 "endianness must be 0 (big-endian) or 1 (little-endian)"); 2311 return NULL; 2312 } 2313 } 2314 2315 static PyObject* 2316 BitstreamRecorder_bits(bitstream_BitstreamRecorder *self, 2317 PyObject *args) 2318 { 2319 return Py_BuildValue("I", self->bitstream->bits_written(self->bitstream)); 2320 } 2321 2322 static PyObject* 2323 BitstreamRecorder_bytes(bitstream_BitstreamRecorder *self, 2324 PyObject *args) 2325 { 2326 return Py_BuildValue("I", 2327 self->bitstream->bits_written(self->bitstream) / 8); 2328 } 2329 2330 static PyObject* 2331 BitstreamRecorder_data(bitstream_BitstreamRecorder *self, 2332 PyObject *args) 2333 { 2334 BitstreamRecorder* recorder = self->bitstream; 2335 2336 return PyBytes_FromStringAndSize( 2337 (char*)recorder->data(recorder), 2338 (Py_ssize_t)recorder->bytes_written(recorder)); 2339 } 2340 2341 static PyObject* 2342 BitstreamRecorder_swap(bitstream_BitstreamRecorder *self, 2343 PyObject *args) 2344 { 2345 bitstream_BitstreamRecorder *to_swap; 2346 2347 if (!PyArg_ParseTuple(args, "O!", 2348 &bitstream_BitstreamRecorderType, &to_swap)) 2349 return NULL; 2350 2351 recorder_swap(&(to_swap->bitstream), &(self->bitstream)); 2352 2353 Py_INCREF(Py_None); 2354 return Py_None; 2355 } 2356 2357 static PyObject* 2358 BitstreamRecorder_reset(bitstream_BitstreamRecorder *self, 2359 PyObject *args) 2360 { 2361 self->bitstream->reset(self->bitstream); 2362 2363 Py_INCREF(Py_None); 2364 return Py_None; 2365 } 2366 2367 static BitstreamWriter* 2368 internal_writer(PyObject *writer) 2369 { 2370 if (Py_TYPE(writer) == &bitstream_BitstreamWriterType) { 2371 bitstream_BitstreamWriter* writer_obj = 2372 (bitstream_BitstreamWriter*)writer; 2373 return writer_obj->bitstream; 2374 } else if (Py_TYPE(writer) == &bitstream_BitstreamRecorderType) { 2375 bitstream_BitstreamRecorder* recorder_obj = 2376 (bitstream_BitstreamRecorder*)writer; 2377 return (BitstreamWriter*)recorder_obj->bitstream; 2378 } else { 2379 return NULL; 2380 } 2381 } 2382 2383 static PyObject* 2384 BitstreamRecorder_copy(bitstream_BitstreamRecorder *self, 2385 PyObject *args) 2386 { 2387 PyObject* bitstreamwriter_obj; 2388 BitstreamWriter* target; 2389 2390 if (!PyArg_ParseTuple(args, "O", &bitstreamwriter_obj)) 2391 return NULL; 2392 2393 if ((target = internal_writer(bitstreamwriter_obj)) != NULL) { 2394 if (!setjmp(*bw_try((BitstreamWriter*)self->bitstream))) { 2395 self->bitstream->copy(self->bitstream, target); 2396 bw_etry((BitstreamWriter*)self->bitstream); 2397 Py_INCREF(Py_None); 2398 return Py_None; 2399 } else { 2400 bw_etry((BitstreamWriter*)self->bitstream); 2401 PyErr_SetString(PyExc_IOError, "I/O error writing stream"); 2402 return NULL; 2403 } 2404 } else { 2405 PyErr_SetString(PyExc_TypeError, 2406 "argument must be a " 2407 "BitstreamWriter or BitstreamRecorder"); 2408 return NULL; 2409 } 2410 } 2411 2412 static PyObject* 2413 BitstreamRecorder_add_callback(bitstream_BitstreamRecorder *self, 2414 PyObject *args) 2415 { 2416 BitstreamWriter *writer = (BitstreamWriter*)self->bitstream; 2417 PyObject* callback; 2418 2419 if (!PyArg_ParseTuple(args, "O", &callback)) 2420 return NULL; 2421 2422 if (!PyCallable_Check(callback)) { 2423 PyErr_SetString(PyExc_TypeError, "callback must be callable"); 2424 return NULL; 2425 } 2426 2427 Py_INCREF(callback); 2428 writer->add_callback(writer, 2429 (bs_callback_f)BitstreamWriter_callback, 2430 callback); 2431 2432 Py_INCREF(Py_None); 2433 return Py_None; 2434 } 2435 2436 static PyObject* 2437 BitstreamRecorder_pop_callback(bitstream_BitstreamRecorder *self, 2438 PyObject *args) 2439 { 2440 BitstreamWriter* writer = (BitstreamWriter*)self->bitstream; 2441 struct bs_callback callback; 2442 PyObject* callback_obj; 2443 2444 if (writer->callbacks != NULL) { 2445 writer->pop_callback(writer, &callback); 2446 callback_obj = callback.data; 2447 /*decref object from stack and then incref object for return 2448 should have a net effect of noop*/ 2449 return callback_obj; 2450 } else { 2451 PyErr_SetString(PyExc_IndexError, "no callbacks to pop"); 2452 return NULL; 2453 } 2454 } 2455 2456 static PyObject* 2457 BitstreamRecorder_call_callbacks(bitstream_BitstreamRecorder *self, 2458 PyObject *args) 2459 { 2460 BitstreamWriter* writer = (BitstreamWriter*)self->bitstream; 2461 uint8_t byte; 2462 2463 if (!PyArg_ParseTuple(args, "b", &byte)) 2464 return NULL; 2465 2466 writer->call_callbacks(writer, byte); 2467 2468 Py_INCREF(Py_None); 2469 return Py_None; 2470 } 2471 2472 static PyObject* 2473 BitstreamRecorder_getpos(bitstream_BitstreamRecorder *self, 2474 PyObject *args) 2475 { 2476 return PyObject_CallFunction( 2477 (PyObject*)&bitstream_BitstreamWriterPositionType, "O", self); 2478 } 2479 2480 static PyObject* 2481 BitstreamRecorder_setpos(bitstream_BitstreamRecorder *self, 2482 PyObject *args) 2483 { 2484 bitstream_BitstreamWriterPosition* pos_obj; 2485 BitstreamWriter *writer = (BitstreamWriter*)self->bitstream; 2486 2487 if (!PyArg_ParseTuple(args, "O!", 2488 &bitstream_BitstreamWriterPositionType, 2489 &pos_obj)) 2490 return NULL; 2491 2492 /*ensure position has come from this reader*/ 2493 if (pos_obj->pos->writer != writer) { 2494 PyErr_SetString(PyExc_IOError, 2495 "position is not from this BitstreamWriter"); 2496 return NULL; 2497 } 2498 2499 /*ensure stream is byte-aligned before setting position*/ 2500 if (!writer->byte_aligned(writer)) { 2501 PyErr_SetString(PyExc_IOError, "stream must be byte-aligned"); 2502 return NULL; 2503 } 2504 2505 if (!setjmp(*bw_try(writer))) { 2506 writer->setpos(writer, pos_obj->pos); 2507 bw_etry(writer); 2508 2509 Py_INCREF(Py_None); 2510 return Py_None; 2511 } else { 2512 /*raise IOError if some problem occurs setting the position*/ 2513 bw_etry(writer); 2514 2515 PyErr_SetString(PyExc_IOError, "unable to set position"); 2516 return NULL; 2517 } 2518 } 2519 2520 static PyObject* 2521 BitstreamRecorder_enter(bitstream_BitstreamRecorder *self, PyObject *args) 2522 { 2523 Py_INCREF(self); 2524 return (PyObject *)self; 2525 } 2526 2527 static PyObject* 2528 BitstreamRecorder_exit(bitstream_BitstreamRecorder *self, PyObject *args) 2529 { 2530 /*close internal stream*/ 2531 self->bitstream->close_internal_stream(self->bitstream); 2532 2533 Py_INCREF(Py_None); 2534 return Py_None; 2535 } 2536 2537 static PyObject* 2538 BitstreamRecorder_close(bitstream_BitstreamRecorder *self, 2539 PyObject *args) 2540 { 2541 self->bitstream->close_internal_stream(self->bitstream); 2542 Py_INCREF(Py_None); 2543 return Py_None; 2544 } 2545 2546 int 2547 BitstreamRecorder_init(bitstream_BitstreamRecorder *self, 2548 PyObject *args) 2549 { 2550 int little_endian; 2551 2552 self->bitstream = NULL; 2553 2554 if (!PyArg_ParseTuple(args, "i", &little_endian)) 2555 return -1; 2556 2557 self->bitstream = bw_open_recorder(little_endian ? 2558 BS_LITTLE_ENDIAN : BS_BIG_ENDIAN); 2559 2560 return 0; 2561 } 2562 2563 void 2564 BitstreamRecorder_dealloc(bitstream_BitstreamRecorder *self) 2565 { 2566 if (self->bitstream != NULL) 2567 self->bitstream->free(self->bitstream); 2568 2569 Py_TYPE(self)->tp_free((PyObject*)self); 2570 } 2571 2572 static PyObject* 2573 BitstreamRecorder_new(PyTypeObject *type, PyObject *args, 2574 PyObject *kwds) 2575 { 2576 bitstream_BitstreamRecorder *self; 2577 2578 self = (bitstream_BitstreamRecorder *)type->tp_alloc(type, 0); 2579 2580 return (PyObject *)self; 2581 } 2582 2583 2584 void 2585 BitstreamWriter_callback(uint8_t byte, PyObject *callback) 2586 { 2587 PyObject* result = PyObject_CallFunction(callback, "B", byte); 2588 2589 if (result != NULL) { 2590 Py_DECREF(result); 2591 } else { 2592 PyErr_PrintEx(0); 2593 } 2594 } 2595 2596 static PyObject* 2597 BitstreamWriterPosition_new(PyTypeObject *type, PyObject *args, 2598 PyObject *kwds) 2599 { 2600 bitstream_BitstreamWriterPosition *self; 2601 2602 self = (bitstream_BitstreamWriterPosition *)type->tp_alloc(type, 0); 2603 2604 return (PyObject *)self; 2605 } 2606 2607 int 2608 BitstreamWriterPosition_init(bitstream_BitstreamWriterPosition *self, 2609 PyObject *args) 2610 { 2611 PyObject *writer_obj; 2612 BitstreamWriter *writer; 2613 2614 self->pos = NULL; 2615 2616 if (!PyArg_ParseTuple(args, "O", &writer_obj)) 2617 return -1; 2618 if ((writer = internal_writer(writer_obj)) == NULL) { 2619 PyErr_SetString( 2620 PyExc_TypeError, 2621 "argument must be BitstreamWriter or BitstreamRecorder"); 2622 return -1; 2623 } 2624 if (!writer->byte_aligned(writer)) { 2625 PyErr_SetString(PyExc_IOError, "stream must be byte-aligned"); 2626 return -1; 2627 } 2628 if (!setjmp(*bw_try(writer))) { 2629 self->pos = writer->getpos(writer); 2630 bw_etry(writer); 2631 return 0; 2632 } else { 2633 bw_etry(writer); 2634 PyErr_SetString(PyExc_IOError, "I/O error getting current position"); 2635 return -1; 2636 } 2637 } 2638 2639 void 2640 BitstreamWriterPosition_dealloc(bitstream_BitstreamWriterPosition *self) 2641 { 2642 /*since the position contains a copy of the "free" function 2643 needed to free the object returned by getpos, 2644 this position object can be safely freed after its parent reader*/ 2645 if (self->pos) { 2646 self->pos->del(self->pos); 2647 } 2648 2649 Py_TYPE(self)->tp_free((PyObject*)self); 2650 } 2651 2652 PyObject* 2653 bitstream_parse_func(PyObject *dummy, PyObject *args) 2654 { 2655 char *format; 2656 int is_little_endian; 2657 char *data; 2658 #ifdef PY_SSIZE_T_CLEAN 2659 Py_ssize_t data_length; 2660 #else 2661 int data_length; 2662 #endif 2663 2664 if (!PyArg_ParseTuple(args, "sis#", 2665 &format, &is_little_endian, &data, &data_length)) { 2666 return NULL; 2667 } else { 2668 BitstreamReader* stream = 2669 br_open_buffer( 2670 (uint8_t*)data, 2671 (unsigned)data_length, 2672 is_little_endian ? BS_LITTLE_ENDIAN : BS_BIG_ENDIAN); 2673 PyObject* values = PyList_New(0); 2674 if (!bitstream_parse(stream, format, values)) { 2675 stream->close(stream); 2676 return values; 2677 } else { 2678 stream->close(stream); 2679 Py_DECREF(values); 2680 return NULL; 2681 } 2682 } 2683 } 2684 2685 PyObject* 2686 bitstream_build_func(PyObject *dummy, PyObject *args) 2687 { 2688 char *format; 2689 int is_little_endian; 2690 PyObject *values; 2691 PyObject *iterator; 2692 2693 if (!PyArg_ParseTuple(args, "siO", &format, &is_little_endian, &values)) { 2694 return NULL; 2695 } else if ((iterator = PyObject_GetIter(values)) == NULL) { 2696 return NULL; 2697 } else { 2698 BitstreamRecorder* stream; 2699 if (is_little_endian) { 2700 stream = bw_open_recorder(BS_LITTLE_ENDIAN); 2701 } else { 2702 stream = bw_open_recorder(BS_BIG_ENDIAN); 2703 } 2704 if (!bitstream_build((BitstreamWriter*)stream, 2705 format, 2706 iterator)) { 2707 PyObject* data = PyBytes_FromStringAndSize( 2708 (char *)stream->data(stream), 2709 (Py_ssize_t)stream->bytes_written(stream)); 2710 stream->close(stream); 2711 Py_DECREF(iterator); 2712 return data; 2713 } else { 2714 stream->close(stream); 2715 Py_DECREF(iterator); 2716 return NULL; 2717 } 2718 } 2719 } 2720 2721 int 2722 bitstream_parse(BitstreamReader* stream, 2723 const char* format, 2724 PyObject* values) 2725 { 2726 bs_instruction_t inst; 2727 2728 do { 2729 unsigned times; 2730 unsigned size; 2731 2732 format = bs_parse_format(format, ×, &size, &inst); 2733 switch (inst) { 2734 case BS_INST_UNSIGNED: 2735 case BS_INST_UNSIGNED64: 2736 case BS_INST_UNSIGNED_BIGINT: 2737 for (; times; times--) { 2738 PyObject *py_value = brpy_read_unsigned(stream, size); 2739 if (py_value != NULL) { 2740 /*append read object to list*/ 2741 const int append_ok = PyList_Append(values, py_value); 2742 Py_DECREF(py_value); 2743 if (append_ok == -1) { 2744 /*append error occurred*/ 2745 return 1; 2746 } 2747 } else { 2748 /*read error occurred*/ 2749 return 1; 2750 } 2751 } 2752 break; 2753 case BS_INST_SIGNED: 2754 case BS_INST_SIGNED64: 2755 case BS_INST_SIGNED_BIGINT: 2756 if (size == 0) { 2757 PyErr_SetString(PyExc_ValueError, "count must be > 0"); 2758 return 1; 2759 } 2760 for (; times; times--) { 2761 PyObject *py_value = brpy_read_signed(stream, size); 2762 if (py_value != NULL) { 2763 /*append read object to list*/ 2764 const int append_ok = PyList_Append(values, py_value); 2765 Py_DECREF(py_value); 2766 if (append_ok == -1) { 2767 /*append error occurred*/ 2768 return 1; 2769 } 2770 } else { 2771 /*read error occurred*/ 2772 return 1; 2773 } 2774 } 2775 break; 2776 case BS_INST_SKIP: 2777 if (!setjmp(*br_try(stream))) { 2778 for (; times; times--) { 2779 stream->skip(stream, size); 2780 } 2781 br_etry(stream); 2782 } else { 2783 br_etry(stream); 2784 PyErr_SetString(PyExc_IOError, "I/O error reading stream"); 2785 return 1; 2786 } 2787 break; 2788 case BS_INST_SKIP_BYTES: 2789 if (!setjmp(*br_try(stream))) { 2790 for (; times; times--) { 2791 stream->skip_bytes(stream, size); 2792 } 2793 br_etry(stream); 2794 } else { 2795 br_etry(stream); 2796 PyErr_SetString(PyExc_IOError, "I/O error reading stream"); 2797 return 1; 2798 } 2799 break; 2800 case BS_INST_BYTES: 2801 for (; times; times--) { 2802 PyObject *py_value = brpy_read_bytes(stream, size); 2803 if (py_value != NULL) { 2804 const int append_ok = PyList_Append(values, py_value); 2805 Py_DECREF(py_value); 2806 if (append_ok == -1) { 2807 /*append error occurred*/ 2808 return 1; 2809 } 2810 } else { 2811 /*read error occurred*/ 2812 return 1; 2813 } 2814 } 2815 break; 2816 case BS_INST_ALIGN: 2817 stream->byte_align(stream); 2818 break; 2819 case BS_INST_EOF: 2820 break; 2821 } 2822 } while (inst != BS_INST_EOF); 2823 2824 return 0; 2825 } 2826 2827 #define MISSING_VALUES "number of items is too short for format" 2828 2829 int 2830 bitstream_build(BitstreamWriter* stream, 2831 const char* format, 2832 PyObject* iterator) 2833 { 2834 bs_instruction_t inst; 2835 2836 do { 2837 unsigned times; 2838 unsigned size; 2839 2840 format = bs_parse_format(format, ×, &size, &inst); 2841 switch (inst) { 2842 case BS_INST_UNSIGNED: 2843 case BS_INST_UNSIGNED64: 2844 case BS_INST_UNSIGNED_BIGINT: 2845 { 2846 for (; times; times--) { 2847 PyObject *py_value = PyIter_Next(iterator); 2848 int result; 2849 2850 if (py_value == NULL) { 2851 /*either iterator exhausted or error*/ 2852 2853 if (!PyErr_Occurred()) { 2854 /*iterator exhausted before values are consumed*/ 2855 PyErr_SetString(PyExc_IndexError, 2856 MISSING_VALUES); 2857 } 2858 return 1; 2859 } 2860 2861 /*perform actual write*/ 2862 result = bwpy_write_unsigned(stream, size, py_value); 2863 Py_DECREF(py_value); 2864 if (result) { 2865 return 1; 2866 } 2867 } 2868 } 2869 break; 2870 case BS_INST_SIGNED: 2871 case BS_INST_SIGNED64: 2872 case BS_INST_SIGNED_BIGINT: 2873 { 2874 if (size == 0) { 2875 PyErr_SetString(PyExc_ValueError, "size must be > 0"); 2876 return 1; 2877 } 2878 for (; times; times--) { 2879 PyObject *py_value = PyIter_Next(iterator); 2880 int result; 2881 2882 if (py_value == NULL) { 2883 /*either iterator exhausted or error*/ 2884 2885 if (!PyErr_Occurred()) { 2886 /*iterator exhausted before values are consumed*/ 2887 PyErr_SetString(PyExc_IndexError, 2888 MISSING_VALUES); 2889 } 2890 return 1; 2891 } 2892 2893 /*ensure value is numeric*/ 2894 if (!PyNumber_Check(py_value)) { 2895 PyErr_SetString(PyExc_TypeError, 2896 "value is not a number"); 2897 Py_DECREF(py_value); 2898 return 1; 2899 } 2900 2901 /*perform actual write*/ 2902 result = bwpy_write_signed(stream, size, py_value); 2903 Py_DECREF(py_value); 2904 if (result) { 2905 return 1; 2906 } 2907 } 2908 } 2909 break; 2910 case BS_INST_SKIP: 2911 if (!setjmp(*bw_try(stream))) { 2912 for (; times; times--) { 2913 stream->write(stream, size, 0); 2914 } 2915 bw_etry(stream); 2916 } else { 2917 bw_etry(stream); 2918 PyErr_SetString(PyExc_IOError, "I/O error writing to stream"); 2919 return 1; 2920 } 2921 break; 2922 case BS_INST_SKIP_BYTES: 2923 if (!setjmp(*bw_try(stream))) { 2924 for (; times; times--) { 2925 stream->write(stream, size, 0); 2926 stream->write(stream, size, 0); 2927 stream->write(stream, size, 0); 2928 stream->write(stream, size, 0); 2929 stream->write(stream, size, 0); 2930 stream->write(stream, size, 0); 2931 stream->write(stream, size, 0); 2932 stream->write(stream, size, 0); 2933 } 2934 bw_etry(stream); 2935 } else { 2936 bw_etry(stream); 2937 PyErr_SetString(PyExc_IOError, "I/O error writing to stream"); 2938 return 1; 2939 } 2940 break; 2941 case BS_INST_BYTES: 2942 for (; times; times--) { 2943 PyObject *py_value = PyIter_Next(iterator); 2944 char *bytes; 2945 Py_ssize_t bytes_len; 2946 2947 if (py_value == NULL) { 2948 /*either iterator exhausted or error*/ 2949 2950 if (!PyErr_Occurred()) { 2951 /*iterator exhausted before values are consumed*/ 2952 PyErr_SetString(PyExc_IndexError, MISSING_VALUES); 2953 } 2954 bw_etry(stream); 2955 return 1; 2956 } 2957 2958 if (PyBytes_AsStringAndSize(py_value, 2959 &bytes, 2960 &bytes_len) == -1) { 2961 /*some error converting object to bytes*/ 2962 Py_DECREF(py_value); 2963 return 1; 2964 } 2965 2966 if (bytes_len < size) { 2967 /*bytes from iterator are too short 2968 compared to size in format string*/ 2969 PyErr_SetString(PyExc_ValueError, 2970 "string length too short"); 2971 Py_DECREF(py_value); 2972 return 1; 2973 } 2974 2975 /*ensure py_value gets DECREFed 2976 especially if a write error occurs*/ 2977 if (!setjmp(*bw_try(stream))) { 2978 stream->write_bytes(stream, 2979 (uint8_t*)bytes, 2980 (unsigned)size); 2981 Py_DECREF(py_value); 2982 bw_etry(stream); 2983 } else { 2984 Py_DECREF(py_value); 2985 bw_etry(stream); 2986 PyErr_SetString(PyExc_ValueError, 2987 "I/O error writing to stream"); 2988 return 1; 2989 } 2990 } 2991 break; 2992 case BS_INST_ALIGN: 2993 if (!setjmp(*bw_try(stream))) { 2994 stream->byte_align(stream); 2995 bw_etry(stream); 2996 } else { 2997 bw_etry(stream); 2998 PyErr_SetString(PyExc_IOError, "I/O error writing to stream"); 2999 return 1; 3000 } 3001 break; 3002 case BS_INST_EOF: 3003 break; 3004 } 3005 } while (inst != BS_INST_EOF); 3006 3007 return 0; 3008 } 3009