1 #if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
2 typedef int Py_ssize_t;
3 #define PY_SSIZE_T_MAX INT_MAX
4 #define PY_SSIZE_T_MIN INT_MIN
5 #endif
6 
7 /********************************************************
8  Audio Tools, a module and set of tools for manipulating audio data
9  Copyright (C) 2007-2014  Brian Langenberger
10 
11  This program is free software; you can redistribute it and/or modify
12  it under the terms of the GNU General Public License as published by
13  the Free Software Foundation; either version 2 of the License, or
14  (at your option) any later version.
15 
16  This program is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  GNU General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with this program; if not, write to the Free Software
23  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
24 *******************************************************/
25 
26 #if PY_MAJOR_VERSION >= 3
27 #define IS_PY3K
28 #endif
29 
30 PyObject*
31 bitstream_format_size(PyObject *dummy, PyObject *args);
32 
33 PyObject*
34 bitstream_format_byte_size(PyObject *dummy, PyObject *args);
35 
36 PyObject*
37 bitstream_parse_func(PyObject *dummy, PyObject *args);
38 
39 PyObject*
40 bitstream_build_func(PyObject *dummy, PyObject *args);
41 
42 PyMethodDef module_methods[] = {
43     {"format_size", (PyCFunction)bitstream_format_size,
44      METH_VARARGS, "Calculate size of format string in bits"}, /*FIXME*/
45     {"format_byte_size", (PyCFunction)bitstream_format_byte_size,
46      METH_VARARGS, "Calculate size of format string in bytes"},
47     {"parse", (PyCFunction)bitstream_parse_func,
48      METH_VARARGS, "parse(format, is_little_endian, data) -> [values]"},
49     {"build", (PyCFunction)bitstream_build_func,
50      METH_VARARGS, "build(format, is_little_endian, [values]) -> data"},
51     {NULL}
52 };
53 
54 /*the BitstreamReader object
55   a simple wrapper around our Bitstream reading struct*/
56 
57 typedef struct {
58     PyObject_HEAD
59 
60     BitstreamReader* bitstream;
61 } bitstream_BitstreamReader;
62 
63 static PyObject*
64 brpy_read_unsigned(BitstreamReader *br, unsigned bits);
65 
66 static PyObject*
67 brpy_read_signed(BitstreamReader *br, unsigned bits);
68 
69 /*reads byte_count bytes from reader to buffer
70   returns 0 on success, 1 if a read error occurs with PyErr set accordingly*/
71 int
72 brpy_read_bytes_chunk(BitstreamReader *reader,
73                       unsigned byte_count,
74                       struct bs_buffer *buffer);
75 
76 /*sets "minimum" to the smaller value of x or y
77   returns the smaller object on success, or NULL with PyErr set
78   if some comparison or conversion error occurs
79 
80   the reference count of either is *not* incremented*/
81 PyObject*
82 brpy_read_bytes_min(PyObject *x, PyObject *y, long *minimum);
83 
84 /*given a byte count as a Python object (presumably numeric)
85   returns a Python string of bytes read or NULL on error*/
86 static PyObject*
87 brpy_read_bytes_obj(BitstreamReader *reader, PyObject *byte_count);
88 
89 /*skips byte_count bytes from reader
90   returns 0 on success, 1 if a read error occurs with PyErr set accordingly*/
91 int
92 brpy_skip_bytes_chunk(BitstreamReader *reader,
93                       unsigned byte_count);
94 
95 /*given a byte count as a Python object (presumably numeric)
96   returns 0 on success, 1 if a read error occurs with PyErr set accordingly*/
97 int
98 brpy_skip_bytes_obj(BitstreamReader *reader, PyObject *byte_count);
99 
100 /*given a byte count, returns a Python string of bytes read
101   or NULL on error*/
102 static PyObject*
103 brpy_read_bytes(BitstreamReader *reader, unsigned byte_count);
104 
105 static PyObject*
106 BitstreamReader_read(bitstream_BitstreamReader *self, PyObject *args);
107 
108 static PyObject*
109 BitstreamReader_byte_align(bitstream_BitstreamReader *self, PyObject *args);
110 
111 static PyObject*
112 BitstreamReader_byte_aligned(bitstream_BitstreamReader *self, PyObject *args);
113 
114 static PyObject*
115 BitstreamReader_skip(bitstream_BitstreamReader *self, PyObject *args);
116 
117 static PyObject*
118 BitstreamReader_skip_bytes(bitstream_BitstreamReader *self, PyObject *args);
119 
120 static PyObject*
121 BitstreamReader_unread(bitstream_BitstreamReader *self, PyObject *args);
122 
123 static PyObject*
124 BitstreamReader_read_signed(bitstream_BitstreamReader *self, PyObject *args);
125 
126 static PyObject*
127 BitstreamReader_unary(bitstream_BitstreamReader *self, PyObject *args);
128 
129 static PyObject*
130 BitstreamReader_skip_unary(bitstream_BitstreamReader *self, PyObject *args);
131 
132 static PyObject*
133 BitstreamReader_read_huffman_code(bitstream_BitstreamReader *self,
134                                   PyObject *args);
135 
136 static PyObject*
137 BitstreamReader_read_bytes(bitstream_BitstreamReader *self,
138                            PyObject *args);
139 
140 static PyObject*
141 BitstreamReader_set_endianness(bitstream_BitstreamReader *self, PyObject *args);
142 
143 static PyObject*
144 BitstreamReader_close(bitstream_BitstreamReader *self, PyObject *args);
145 
146 static PyObject*
147 BitstreamReader_getpos(bitstream_BitstreamReader *self, PyObject *args);
148 
149 static PyObject*
150 BitstreamReader_setpos(bitstream_BitstreamReader *self, PyObject *args);
151 
152 static PyObject*
153 BitstreamReader_seek(bitstream_BitstreamReader *self, PyObject *args);
154 
155 static PyObject*
156 BitstreamReader_add_callback(bitstream_BitstreamReader *self, PyObject *args);
157 
158 static PyObject*
159 BitstreamReader_pop_callback(bitstream_BitstreamReader *self, PyObject *args);
160 
161 static PyObject*
162 BitstreamReader_call_callbacks(bitstream_BitstreamReader *self, PyObject *args);
163 
164 static PyObject*
165 BitstreamReader_substream(bitstream_BitstreamReader *self, PyObject *args);
166 
167 static PyObject*
168 BitstreamReader_parse(bitstream_BitstreamReader *self, PyObject *args);
169 
170 int
171 BitstreamReader_init(bitstream_BitstreamReader *self, PyObject *args);
172 
173 static PyObject*
174 BitstreamReader_enter(bitstream_BitstreamReader *self, PyObject *args);
175 
176 static PyObject*
177 BitstreamReader_exit(bitstream_BitstreamReader *self, PyObject *args);
178 
179 PyMethodDef BitstreamReader_methods[] = {
180     {"read", (PyCFunction)BitstreamReader_read, METH_VARARGS,
181      "read(bits) -> unsigned int"},
182     {"skip", (PyCFunction)BitstreamReader_skip, METH_VARARGS,
183      "skip(bits)\n"
184      "skips over the given number of bits"},
185     {"skip_bytes", (PyCFunction)BitstreamReader_skip_bytes, METH_VARARGS,
186      "skip_bytes(bytes)\n"
187      "skips over the given number of bytes"},
188     {"byte_align", (PyCFunction)BitstreamReader_byte_align, METH_NOARGS,
189      "byte_align()\n"
190      "moves to the next whole byte boundary, if necessary"},
191     {"byte_aligned", (PyCFunction)BitstreamReader_byte_aligned, METH_NOARGS,
192      "byte_aligned() -> True if the stream is currently byte-aligned"},
193     {"unread", (PyCFunction)BitstreamReader_unread, METH_VARARGS,
194      "unread(bit)\n"
195      "pushes a single bit back into the stream"},
196     {"read_signed", (PyCFunction)BitstreamReader_read_signed, METH_VARARGS,
197      "read_signed(bits) -> signed int"},
198     {"unary", (PyCFunction)BitstreamReader_unary, METH_VARARGS,
199      "unary(stop_bit) -> unsigned int\n"
200      "counts the number of bits until the next stop bit"},
201     {"skip_unary", (PyCFunction)BitstreamReader_skip_unary, METH_VARARGS,
202      "skip_unary(stop_bit)\n"
203      "skips a number of bits until the next stop bit"},
204     {"read_huffman_code", (PyCFunction)BitstreamReader_read_huffman_code,
205      METH_VARARGS,
206      "read_huffman_code(huffman_tree) -> int\n"
207      "given a compiled HuffmanTree, returns the next code from the stream"},
208     {"read_bytes", (PyCFunction)BitstreamReader_read_bytes, METH_VARARGS,
209      "read_bytes(bytes) -> string"},
210     {"set_endianness", (PyCFunction)BitstreamReader_set_endianness,
211      METH_VARARGS,
212      "set_endianness(endianness)\n"
213      "where 0 = big endian, 1 = little-endian\n"
214      "the stream is automatically byte-aligned"},
215     {"parse", (PyCFunction)BitstreamReader_parse, METH_VARARGS,
216      "parse(format_string) -> [value1, value2, ...]\n"
217      "where \"format_string\" maps to the calls:\n"
218      "\"#u\" -> read(#)\n"
219      "\"#s\" -> read_signed(#)\n"
220      "\"#p\" -> skip(#)\n"
221      "\"#P\" -> skip_bytes(#)\n"
222      "\"#b\" -> read_bytes(#)\n"
223      "\"a\"  -> byte_align()\n\n"
224      "for instance:\n"
225      "r.parse(\"3u 4s 36u\") == [r.read(3), r.read_signed(4), r.read(36)]"},
226     {"close", (PyCFunction)BitstreamReader_close, METH_NOARGS,
227      "close()\n"
228      "closes the stream and any underlying file object"},
229     {"getpos", (PyCFunction)BitstreamReader_getpos, METH_NOARGS,
230      "getpos() -> position"},
231     {"setpos", (PyCFunction)BitstreamReader_setpos, METH_VARARGS,
232      "setpos(position)"},
233     {"seek", (PyCFunction)BitstreamReader_seek, METH_VARARGS,
234      "seek(position, whence)\n"
235      "positions the stream at the given position where\n"
236      "position is stream position in bytes and\n"
237      "whence 0 = stream start, 1 = current position, 2 = stream end\n"
238      "no callbacks are performed on intervening bytes"},
239     {"add_callback", (PyCFunction)BitstreamReader_add_callback, METH_VARARGS,
240      "add_callback(function)\n"
241      "where \"function\" takes a single byte as an argument\n"
242      "and is called upon each read byte from the stream"},
243     {"pop_callback", (PyCFunction)BitstreamReader_pop_callback, METH_NOARGS,
244      "pop_callback() -> function\n"
245      "removes and returns the most recently added callback"},
246     {"call_callbacks", (PyCFunction)BitstreamReader_call_callbacks,
247      METH_VARARGS,
248      "call_callbacks(byte)\n"
249      "calls the attached callbacks as if the byte had been read"},
250     {"substream", (PyCFunction)BitstreamReader_substream, METH_VARARGS,
251      "substream(bytes) -> BitstreamReader\n"
252      "returns a sub-reader containing the given number of input bytes"},
253     {"__enter__", (PyCFunction)BitstreamReader_enter,
254      METH_NOARGS, "enter() -> self"},
255     {"__exit__", (PyCFunction)BitstreamReader_exit,
256      METH_VARARGS, "exit(exc_type, exc_value, traceback) -> None"},
257     {NULL}
258 };
259 
260 void
261 BitstreamReader_dealloc(bitstream_BitstreamReader *self);
262 
263 static PyObject*
264 BitstreamReader_new(PyTypeObject *type, PyObject *args,
265                     PyObject *kwds);
266 
267 void
268 BitstreamReader_callback(uint8_t byte, PyObject *callback);
269 
270 PyTypeObject bitstream_BitstreamReaderType = {
271     PyVarObject_HEAD_INIT(NULL, 0)
272     "bitstream.BitstreamReader",    /*tp_name*/
273     sizeof(bitstream_BitstreamReader), /*tp_basicsize*/
274     0,                         /*tp_itemsize*/
275     (destructor)BitstreamReader_dealloc, /*tp_dealloc*/
276     0,                         /*tp_print*/
277     0,                         /*tp_getattr*/
278     0,                         /*tp_setattr*/
279     0,                         /*tp_compare*/
280     0,                         /*tp_repr*/
281     0,                         /*tp_as_number*/
282     0,                         /*tp_as_sequence*/
283     0,                         /*tp_as_mapping*/
284     0,                         /*tp_hash */
285     0,                         /*tp_call*/
286     0,                         /*tp_str*/
287     0,                         /*tp_getattro*/
288     0,                         /*tp_setattro*/
289     0,                         /*tp_as_buffer*/
290     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
291     "BitstreamReader(file, endianness)", /* tp_doc */
292     0,                         /* tp_traverse */
293     0,                         /* tp_clear */
294     0,                         /* tp_richcompare */
295     0,                         /* tp_weaklistoffset */
296     0,                         /* tp_iter */
297     0,                         /* tp_iternext */
298     BitstreamReader_methods,   /* tp_methods */
299     0,                         /* tp_members */
300     0,                         /* tp_getset */
301     0,                         /* tp_base */
302     0,                         /* tp_dict */
303     0,                         /* tp_descr_get */
304     0,                         /* tp_descr_set */
305     0,                         /* tp_dictoffset */
306     (initproc)BitstreamReader_init,/* tp_init */
307     0,                         /* tp_alloc */
308     BitstreamReader_new,       /* tp_new */
309 };
310 
311 
312 typedef struct {
313     PyObject_HEAD
314 
315     br_huffman_table_t* br_table;
316     bw_huffman_table_t* bw_table;
317 } bitstream_HuffmanTree;
318 
319 static PyObject*
320 HuffmanTree_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
321 
322 int
323 HuffmanTree_init(bitstream_HuffmanTree *self, PyObject *args);
324 
325 void
326 HuffmanTree_dealloc(bitstream_HuffmanTree *self);
327 
328 
329 PyTypeObject bitstream_HuffmanTreeType = {
330     PyVarObject_HEAD_INIT(NULL, 0)
331     "bitstream.HuffmanTree",    /*tp_name*/
332     sizeof(bitstream_HuffmanTree), /*tp_basicsize*/
333     0,                         /*tp_itemsize*/
334     (destructor)HuffmanTree_dealloc, /*tp_dealloc*/
335     0,                         /*tp_print*/
336     0,                         /*tp_getattr*/
337     0,                         /*tp_setattr*/
338     0,                         /*tp_compare*/
339     0,                         /*tp_repr*/
340     0,                         /*tp_as_number*/
341     0,                         /*tp_as_sequence*/
342     0,                         /*tp_as_mapping*/
343     0,                         /*tp_hash */
344     0,                         /*tp_call*/
345     0,                         /*tp_str*/
346     0,                         /*tp_getattro*/
347     0,                         /*tp_setattro*/
348     0,                         /*tp_as_buffer*/
349     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
350     "Huffman Tree objects",    /* tp_doc */
351     0,                         /* tp_traverse */
352     0,                         /* tp_clear */
353     0,                         /* tp_richcompare */
354     0,                         /* tp_weaklistoffset */
355     0,                         /* tp_iter */
356     0,                         /* tp_iternext */
357     0,                         /* tp_methods */
358     0,                         /* tp_members */
359     0,                         /* tp_getset */
360     0,                         /* tp_base */
361     0,                         /* tp_dict */
362     0,                         /* tp_descr_get */
363     0,                         /* tp_descr_set */
364     0,                         /* tp_dictoffset */
365     (initproc)HuffmanTree_init, /* tp_init */
366     0,                         /* tp_alloc */
367     HuffmanTree_new,          /* tp_new */
368 };
369 
370 /*BitstreamReaderPosition is an opaque container for positions
371   returned by BitstreamReader.getpos()
372   it has no methods or attributes and can't even be instantiated directly*/
373 typedef struct {
374     PyObject_HEAD
375 
376     br_pos_t *pos;
377 } bitstream_BitstreamReaderPosition;
378 
379 static PyObject*
380 BitstreamReaderPosition_new(PyTypeObject *type, PyObject *args,
381                             PyObject *kwds);
382 
383 int
384 BitstreamReaderPosition_init(bitstream_BitstreamReaderPosition *self,
385                              PyObject *args);
386 
387 void
388 BitstreamReaderPosition_dealloc(bitstream_BitstreamReaderPosition *self);
389 
390 PyTypeObject bitstream_BitstreamReaderPositionType = {
391     PyVarObject_HEAD_INIT(NULL, 0)
392     "bitstream.BitstreamReaderPosition",    /*tp_name*/
393     sizeof(bitstream_BitstreamReaderPosition), /*tp_basicsize*/
394     0,                         /*tp_itemsize*/
395     (destructor)BitstreamReaderPosition_dealloc, /*tp_dealloc*/
396     0,                         /*tp_print*/
397     0,                         /*tp_getattr*/
398     0,                         /*tp_setattr*/
399     0,                         /*tp_compare*/
400     0,                         /*tp_repr*/
401     0,                         /*tp_as_number*/
402     0,                         /*tp_as_sequence*/
403     0,                         /*tp_as_mapping*/
404     0,                         /*tp_hash */
405     0,                         /*tp_call*/
406     0,                         /*tp_str*/
407     0,                         /*tp_getattro*/
408     0,                         /*tp_setattro*/
409     0,                         /*tp_as_buffer*/
410     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
411     "BitstreamReaderPosition", /* tp_doc */
412     0,                         /* tp_traverse */
413     0,                         /* tp_clear */
414     0,                         /* tp_richcompare */
415     0,                         /* tp_weaklistoffset */
416     0,                         /* tp_iter */
417     0,                         /* tp_iternext */
418     0,                         /* tp_methods */
419     0,                         /* tp_members */
420     0,                         /* tp_getset */
421     0,                         /* tp_base */
422     0,                         /* tp_dict */
423     0,                         /* tp_descr_get */
424     0,                         /* tp_descr_set */
425     0,                         /* tp_dictoffset */
426     (initproc)BitstreamReaderPosition_init, /* tp_init */
427     0,                         /* tp_alloc */
428     BitstreamReaderPosition_new, /* tp_new */
429 };
430 
431 PyObject*
bitstream_format_size(PyObject * dummy,PyObject * args)432 bitstream_format_size(PyObject *dummy, PyObject *args)
433 {
434     char* format_string;
435 
436     if (!PyArg_ParseTuple(args, "s", &format_string))
437         return NULL;
438 
439     return Py_BuildValue("I", bs_format_size(format_string));
440 }
441 
442 PyObject*
bitstream_format_byte_size(PyObject * dummy,PyObject * args)443 bitstream_format_byte_size(PyObject *dummy, PyObject *args)
444 {
445     char* format_string;
446 
447     if (!PyArg_ParseTuple(args, "s", &format_string))
448         return NULL;
449 
450     return Py_BuildValue("I", bs_format_byte_size(format_string));
451 }
452 
453 typedef struct {
454     PyObject_HEAD
455 
456     BitstreamWriter* bitstream;
457 } bitstream_BitstreamWriter;
458 
459 static PyObject*
460 bwpy_min_unsigned(unsigned bits);
461 
462 static PyObject*
463 bwpy_max_unsigned(unsigned bits);
464 
465 static PyObject*
466 bwpy_min_signed(unsigned bits);
467 
468 static PyObject*
469 bwpy_max_signed(unsigned bits);
470 
471 static int
472 bwpy_in_range(PyObject *min_value, PyObject *value, PyObject *max_value);
473 
474 static int
475 bw_validate_unsigned_range(unsigned bits, PyObject *value);
476 
477 static int
478 bw_validate_signed_range(unsigned bits, PyObject *value);
479 
480 static int
481 bwpy_write_unsigned(BitstreamWriter *bw, unsigned bits, PyObject *value);
482 
483 static int
484 bwpy_write_signed(BitstreamWriter *bw, unsigned bits, PyObject *value);
485 
486 static PyObject*
487 BitstreamWriter_write(bitstream_BitstreamWriter *self, PyObject *args);
488 
489 static PyObject*
490 BitstreamWriter_write_signed(bitstream_BitstreamWriter *self, PyObject *args);
491 
492 static PyObject*
493 BitstreamWriter_unary(bitstream_BitstreamWriter *self, PyObject *args);
494 
495 static PyObject*
496 BitstreamWriter_write_huffman_code(bitstream_BitstreamWriter *self,
497                                    PyObject *args);
498 
499 static PyObject*
500 BitstreamWriter_byte_align(bitstream_BitstreamWriter *self, PyObject *args);
501 
502 static PyObject*
503 BitstreamWriter_byte_aligned(bitstream_BitstreamWriter *self, PyObject *args);
504 
505 static PyObject*
506 BitstreamWriter_set_endianness(bitstream_BitstreamWriter *self,
507                                PyObject *args);
508 
509 static PyObject*
510 BitstreamWriter_write_bytes(bitstream_BitstreamWriter *self,
511                             PyObject *args);
512 
513 static PyObject*
514 BitstreamWriter_add_callback(bitstream_BitstreamWriter *self,
515                              PyObject *args);
516 
517 static PyObject*
518 BitstreamWriter_pop_callback(bitstream_BitstreamWriter *self,
519                              PyObject *args);
520 
521 static PyObject*
522 BitstreamWriter_call_callbacks(bitstream_BitstreamWriter *self,
523                                PyObject *args);
524 
525 static PyObject*
526 BitstreamWriter_getpos(bitstream_BitstreamWriter *self,
527                        PyObject *args);
528 
529 static PyObject*
530 BitstreamWriter_setpos(bitstream_BitstreamWriter *self,
531                        PyObject *args);
532 
533 static PyObject*
534 BitstreamWriter_build(bitstream_BitstreamWriter *self, PyObject *args);
535 
536 static PyObject*
537 BitstreamWriter_flush(bitstream_BitstreamWriter *self, PyObject *args);
538 
539 static PyObject*
540 BitstreamWriter_close(bitstream_BitstreamWriter *self, PyObject *args);
541 
542 static PyObject*
543 BitstreamWriter_enter(bitstream_BitstreamWriter *self, PyObject *args);
544 
545 static PyObject*
546 BitstreamWriter_exit(bitstream_BitstreamWriter *self, PyObject *args);
547 
548 int
549 BitstreamWriter_init(bitstream_BitstreamWriter *self, PyObject *args);
550 
551 PyMethodDef BitstreamWriter_methods[] = {
552     {"write", (PyCFunction)BitstreamWriter_write, METH_VARARGS,
553      "write(bits, unsigned int)"},
554     {"write_signed", (PyCFunction)BitstreamWriter_write_signed, METH_VARARGS,
555      "write_signed(bits, signed int)"},
556     {"unary", (PyCFunction)BitstreamWriter_unary, METH_VARARGS,
557      "unary(stop_bit, unsigned int)\n"
558      "where \"stop_bit\" must be 0 or 1\n"
559      "writes value as the given number of not stop_bit values (1 or 0)\n"
560      "followed by a stop_bit"},
561     {"write_huffman_code",
562     (PyCFunction)BitstreamWriter_write_huffman_code,
563      METH_VARARGS, "write_huffman_code(huffman_tree, value)\n"
564      "given a compiled HuffmanTree and int value,\n"
565      "writes that value to the stream"},
566     {"byte_align", (PyCFunction)BitstreamWriter_byte_align, METH_NOARGS,
567      "byte_align()\n"
568      "pads the stream with 0 bits until the next whole byte"},
569     {"byte_aligned", (PyCFunction)BitstreamWriter_byte_aligned, METH_NOARGS,
570      "byte_aligned() -> True if the stream is currently byte-aligned"},
571     {"flush", (PyCFunction)BitstreamWriter_flush, METH_NOARGS,
572      "flush()\n"
573      "flushes pending data to any underlying file object"},
574     {"close", (PyCFunction)BitstreamWriter_close, METH_NOARGS,
575      "close()\n"
576      "closes the stream and any underlying file object"},
577     {"set_endianness", (PyCFunction)BitstreamWriter_set_endianness,
578      METH_VARARGS,
579      "set_endianness(endianness)\n"
580      "where 0 = big endian, 1 = little endian"},
581     {"write_bytes", (PyCFunction)BitstreamWriter_write_bytes, METH_VARARGS,
582      "write_bytes(bytes, string)"},
583     {"build", (PyCFunction)BitstreamWriter_build, METH_VARARGS,
584      "build(format_string, [value1, value2, ...])\n"
585      "where \"format_string\" maps to the calls:\n"
586      "\"#u\" -> write(#, unsigned int value)\n"
587      "\"#s\" -> write_signed(#, signed int value)\n"
588      "\"#p\" -> write(#, 0)\n"
589      "\"#P\" -> write(# * 8, 0)\n"
590      "\"#b\" -> write_bytes(#, string value)\n"
591      "\"a\"  -> byte_align()\n\n"
592      "for instance:\n"
593      "w.build(\"3u 4s 36u\", [1, -2, 3L])\n   ==\n"
594      "w.write(3, 1); w.write_signed(4, -2); w.write(36, 3L)"},
595     {"add_callback", (PyCFunction)BitstreamWriter_add_callback, METH_VARARGS,
596      "add_callback(function)\n"
597      "where \"function\" takes a single byte as an argument\n"
598      "and is called upon each written byte to the stream"},
599     {"pop_callback", (PyCFunction)BitstreamWriter_pop_callback, METH_NOARGS,
600      "pop_callback() -> function\n"
601      "removes and returns the most recently added callback"},
602     {"call_callbacks", (PyCFunction)BitstreamWriter_call_callbacks,
603      METH_VARARGS,
604      "call_callbacks(byte)\n"
605      "calls the attached callbacks as if the byte had been written"},
606     {"getpos", (PyCFunction)BitstreamWriter_getpos, METH_NOARGS,
607      "getpos() -> position"},
608     {"setpos", (PyCFunction)BitstreamWriter_setpos, METH_VARARGS,
609      "setpos(position)"},
610     {"__enter__", (PyCFunction)BitstreamWriter_enter,
611      METH_NOARGS, "enter() -> self"},
612     {"__exit__", (PyCFunction)BitstreamWriter_exit,
613      METH_VARARGS, "exit(exc_type, exc_value, traceback) -> None"},
614     {NULL}
615 };
616 
617 void
618 BitstreamWriter_dealloc(bitstream_BitstreamWriter *self);
619 
620 static PyObject*
621 BitstreamWriter_new(PyTypeObject *type, PyObject *args,
622                     PyObject *kwds);
623 
624 PyTypeObject bitstream_BitstreamWriterType = {
625     PyVarObject_HEAD_INIT(NULL, 0)
626     "bitstream.BitstreamWriter", /*tp_name*/
627     sizeof(bitstream_BitstreamWriter), /*tp_basicsize*/
628     0,                         /*tp_itemsize*/
629     (destructor)BitstreamWriter_dealloc, /*tp_dealloc*/
630     0,                         /*tp_print*/
631     0,                         /*tp_getattr*/
632     0,                         /*tp_setattr*/
633     0,                         /*tp_compare*/
634     0,                         /*tp_repr*/
635     0,                         /*tp_as_number*/
636     0,                         /*tp_as_sequence*/
637     0,                         /*tp_as_mapping*/
638     0,                         /*tp_hash */
639     0,                         /*tp_call*/
640     0,                         /*tp_str*/
641     0,                         /*tp_getattro*/
642     0,                         /*tp_setattro*/
643     0,                         /*tp_as_buffer*/
644     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
645     "BitstreamWriter objects", /* tp_doc */
646     0,                         /* tp_traverse */
647     0,                         /* tp_clear */
648     0,                         /* tp_richcompare */
649     0,                         /*  tp_weaklistoffset */
650     0,                         /* tp_iter */
651     0,                         /* tp_iternext */
652     BitstreamWriter_methods,   /* tp_methods */
653     0,                         /* tp_members */
654     0,                         /* tp_getset */
655     0,                         /* tp_base */
656     0,                         /* tp_dict */
657     0,                         /* tp_descr_get */
658     0,                         /* tp_descr_set */
659     0,                         /* tp_dictoffset */
660     (initproc)BitstreamWriter_init,/* tp_init */
661     0,                         /* tp_alloc */
662     BitstreamWriter_new,       /* tp_new */
663 };
664 
665 
666 typedef struct {
667     PyObject_HEAD
668 
669     BitstreamRecorder* bitstream;
670 } bitstream_BitstreamRecorder;
671 
672 static PyObject*
673 BitstreamRecorder_write(bitstream_BitstreamRecorder *self,
674                         PyObject *args);
675 
676 static PyObject*
677 BitstreamRecorder_write_signed(bitstream_BitstreamRecorder *self,
678                                PyObject *args);
679 
680 static PyObject*
681 BitstreamRecorder_unary(bitstream_BitstreamRecorder *self,
682                         PyObject *args);
683 
684 static PyObject*
685 BitstreamRecorder_write_huffman_code(bitstream_BitstreamRecorder *self,
686                                      PyObject *args);
687 
688 static PyObject*
689 BitstreamRecorder_byte_align(bitstream_BitstreamRecorder *self,
690                              PyObject *args);
691 
692 static PyObject*
693 BitstreamRecorder_byte_aligned(bitstream_BitstreamRecorder *self,
694                                PyObject *args);
695 
696 static PyObject*
697 BitstreamRecorder_set_endianness(bitstream_BitstreamRecorder *self,
698                                  PyObject *args);
699 
700 static PyObject*
701 BitstreamRecorder_bits(bitstream_BitstreamRecorder *self,
702                        PyObject *args);
703 
704 static PyObject*
705 BitstreamRecorder_bytes(bitstream_BitstreamRecorder *self,
706                         PyObject *args);
707 
708 static PyObject*
709 BitstreamRecorder_data(bitstream_BitstreamRecorder *self,
710                        PyObject *args);
711 
712 static PyObject*
713 BitstreamRecorder_swap(bitstream_BitstreamRecorder *self,
714                        PyObject *args);
715 
716 static PyObject*
717 BitstreamRecorder_write_bytes(bitstream_BitstreamRecorder *self,
718                               PyObject *args);
719 
720 static PyObject*
721 BitstreamRecorder_build(bitstream_BitstreamRecorder *self,
722                         PyObject *args);
723 
724 static PyObject*
725 BitstreamRecorder_add_callback(bitstream_BitstreamRecorder *self,
726                                PyObject *args);
727 
728 static PyObject*
729 BitstreamRecorder_pop_callback(bitstream_BitstreamRecorder *self,
730                                PyObject *args);
731 
732 static PyObject*
733 BitstreamRecorder_call_callbacks(bitstream_BitstreamRecorder *self,
734                                  PyObject *args);
735 
736 static PyObject*
737 BitstreamRecorder_flush(bitstream_BitstreamRecorder *self,
738                         PyObject *args);
739 
740 static PyObject*
741 BitstreamRecorder_reset(bitstream_BitstreamRecorder *self,
742                         PyObject *args);
743 
744 /*returns the internal BitstreamWriter struct of the given object
745   or NULL if it is not a BitstreamWriter/Recorder*/
746 static BitstreamWriter*
747 internal_writer(PyObject *writer);
748 
749 static PyObject*
750 BitstreamRecorder_copy(bitstream_BitstreamRecorder *self,
751                        PyObject *args);
752 
753 static PyObject*
754 BitstreamRecorder_getpos(bitstream_BitstreamRecorder *self,
755                          PyObject *args);
756 
757 static PyObject*
758 BitstreamRecorder_setpos(bitstream_BitstreamRecorder *self,
759                          PyObject *args);
760 
761 static PyObject*
762 BitstreamRecorder_close(bitstream_BitstreamRecorder *self,
763                         PyObject *args);
764 
765 static PyObject*
766 BitstreamRecorder_enter(bitstream_BitstreamRecorder *self, PyObject *args);
767 
768 static PyObject*
769 BitstreamRecorder_exit(bitstream_BitstreamRecorder *self, PyObject *args);
770 
771 int
772 BitstreamRecorder_init(bitstream_BitstreamRecorder *self,
773                        PyObject *args);
774 
775 PyMethodDef BitstreamRecorder_methods[] = {
776     {"write", (PyCFunction)BitstreamRecorder_write, METH_VARARGS,
777      "write(bits, unsigned int)"},
778     {"write_signed", (PyCFunction)BitstreamRecorder_write_signed, METH_VARARGS,
779      "write_signed(bits, signed int)"},
780     {"unary", (PyCFunction)BitstreamRecorder_unary, METH_VARARGS,
781      "unary(stop_bit, unsigned int)\n"
782      "where \"stop_bit\" must be 0 or 1\n"
783      "writes value as the given number of not stop_bit values (1 or 0)\n"
784      "followed by a stop_bit"},
785     {"write_huffman_code",
786     (PyCFunction)BitstreamRecorder_write_huffman_code,
787      METH_VARARGS, "write_huffman_code(huffman_tree, value)\n"
788      "given a compiled HuffmanTree and int value,\n"
789      "writes that value to the stream"},
790     {"byte_align", (PyCFunction)BitstreamRecorder_byte_align, METH_NOARGS,
791      "byte_align()\n"
792      "pads the stream with 0 bits until the next whole byte"},
793     {"byte_aligned", (PyCFunction)BitstreamRecorder_byte_aligned, METH_NOARGS,
794      "byte_aligned() -> True if the stream is currently byte-aligned"},
795     {"flush", (PyCFunction)BitstreamRecorder_flush, METH_NOARGS,
796      "flush()\n"
797      "flushes pending data to any underlying file object"},
798     {"close", (PyCFunction)BitstreamRecorder_close, METH_NOARGS,
799     "close()\n"},
800     {"set_endianness", (PyCFunction)BitstreamRecorder_set_endianness,
801      METH_VARARGS,
802      "set_endianness(endianness)\n"
803      "where 0 = big endian, 1 = little endian"},
804     {"write_bytes", (PyCFunction)BitstreamRecorder_write_bytes,
805      METH_VARARGS,
806      "write_bytes(bytes, string)"},
807     {"bits", (PyCFunction)BitstreamRecorder_bits, METH_NOARGS,
808      "bits() -> unsigned int\n"
809      "returns the total number of bits written thus far"},
810     {"bytes", (PyCFunction)BitstreamRecorder_bytes, METH_NOARGS,
811      "bytes() -> unsigned int\n"
812      "returns the total number of bytes written thus far"},
813     {"data", (PyCFunction)BitstreamRecorder_data, METH_NOARGS,
814      "data() -> string\n"
815      "returns the written data as a string"},
816     {"reset", (PyCFunction)BitstreamRecorder_reset, METH_NOARGS,
817      "reset()\n"
818      "removes all written data and resets the stream for new data"},
819     {"copy", (PyCFunction)BitstreamRecorder_copy, METH_VARARGS,
820      "copy(target)\n"
821      "copies the written data to \"target\", which must be a\n"
822      "BitstreamWriter or Recorder"},
823     {"build", (PyCFunction)BitstreamRecorder_build, METH_VARARGS,
824      "build(format_string, [value1, value2, ...])\n"
825      "where \"format_string\" maps to the calls:\n"
826      "\"#u\" -> write(#, unsigned int value)\n"
827      "\"#s\" -> write_signed(#, signed int value)\n"
828      "\"#p\" -> write(#, 0)\n"
829      "\"#P\" -> write(# * 8, 0)\n"
830      "\"#b\" -> write_bytes(#, string value)\n"
831      "\"a\"  -> byte_align()\n\n"
832      "for instance:\n"
833      "r.build(\"3u 4s 36u\", [1, -2, 3L])\n   ==\n"
834      "r.write(3, 1); r.write_signed(4, -2); r.write(36, 3L)"},
835     {"swap", (PyCFunction)BitstreamRecorder_swap, METH_VARARGS,
836      "swap(recorder)\n"
837      "swaps our written data with that of another BitstreamRecorder"},
838     {"add_callback", (PyCFunction)BitstreamRecorder_add_callback,
839      METH_VARARGS,
840      "add_callback(function)\n"
841      "where \"function\" takes a single byte as an argument\n"
842      "and is called upon each written byte to the stream"},
843     {"pop_callback", (PyCFunction)BitstreamRecorder_pop_callback,
844      METH_NOARGS,
845      "pop_callback() -> function\n"
846      "removes and returns the most recently added callback"},
847     {"call_callbacks", (PyCFunction)BitstreamRecorder_call_callbacks,
848      METH_VARARGS,
849      "call_callbacks(byte)\n"
850      "calls the attached callbacks as if the byte had been written"},
851     {"getpos", (PyCFunction)BitstreamRecorder_getpos, METH_NOARGS,
852      "getpos() -> position"},
853     {"setpos", (PyCFunction)BitstreamRecorder_setpos, METH_VARARGS,
854      "setpos(position)"},
855     {"__enter__", (PyCFunction)BitstreamRecorder_enter,
856      METH_NOARGS, "enter() -> self"},
857     {"__exit__", (PyCFunction)BitstreamRecorder_exit,
858      METH_VARARGS, "exit(exc_type, exc_value, traceback) -> None"},
859     {NULL}
860 };
861 
862 void
863 BitstreamRecorder_dealloc(bitstream_BitstreamRecorder *self);
864 
865 static PyObject*
866 BitstreamRecorder_new(PyTypeObject *type, PyObject *args,
867                       PyObject *kwds);
868 
869 PyTypeObject bitstream_BitstreamRecorderType = {
870     PyVarObject_HEAD_INIT(NULL, 0)
871     "bitstream.BitstreamRecorder",    /*tp_name*/
872     sizeof(bitstream_BitstreamRecorder), /*tp_basicsize*/
873     0,                         /*tp_itemsize*/
874     (destructor)BitstreamRecorder_dealloc, /*tp_dealloc*/
875     0,                         /*tp_print*/
876     0,                         /*tp_getattr*/
877     0,                         /*tp_setattr*/
878     0,                         /*tp_compare*/
879     0,                         /*tp_repr*/
880     0,                         /*tp_as_number*/
881     0,                         /*tp_as_sequence*/
882     0,                         /*tp_as_mapping*/
883     0,                         /*tp_hash */
884     0,                         /*tp_call*/
885     0,                         /*tp_str*/
886     0,                         /*tp_getattro*/
887     0,                         /*tp_setattro*/
888     0,                         /*tp_as_buffer*/
889     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
890     "BitstreamRecorder objects", /* tp_doc */
891     0,                         /* tp_traverse */
892     0,                         /* tp_clear */
893     0,                         /* tp_richcompare */
894     0,                         /*  tp_weaklistoffset */
895     0,                         /* tp_iter */
896     0,                         /* tp_iternext */
897     BitstreamRecorder_methods, /* tp_methods */
898     0,                         /* tp_members */
899     0,                         /* tp_getset */
900     0,                         /* tp_base */
901     0,                         /* tp_dict */
902     0,                         /* tp_descr_get */
903     0,                         /* tp_descr_set */
904     0,                         /* tp_dictoffset */
905     (initproc)BitstreamRecorder_init, /* tp_init */
906     0,                         /* tp_alloc */
907     BitstreamRecorder_new,       /* tp_new */
908 };
909 
910 /*BitstreamWriterPosition is an opaque container for positions
911   returned by BitstreamWriter.getpos()
912   it has no methods or attributes and can't even be instantiated directly*/
913 typedef struct {
914     PyObject_HEAD
915 
916     bw_pos_t *pos;
917 } bitstream_BitstreamWriterPosition;
918 
919 static PyObject*
920 BitstreamWriterPosition_new(PyTypeObject *type, PyObject *args,
921                             PyObject *kwds);
922 
923 int
924 BitstreamWriterPosition_init(bitstream_BitstreamWriterPosition *self,
925                              PyObject *args);
926 
927 void
928 BitstreamWriterPosition_dealloc(bitstream_BitstreamWriterPosition *self);
929 
930 PyTypeObject bitstream_BitstreamWriterPositionType = {
931     PyVarObject_HEAD_INIT(NULL, 0)
932     "bitstream.BitstreamWriterPosition",    /*tp_name*/
933     sizeof(bitstream_BitstreamWriterPosition), /*tp_basicsize*/
934     0,                         /*tp_itemsize*/
935     (destructor)BitstreamWriterPosition_dealloc, /*tp_dealloc*/
936     0,                         /*tp_print*/
937     0,                         /*tp_getattr*/
938     0,                         /*tp_setattr*/
939     0,                         /*tp_compare*/
940     0,                         /*tp_repr*/
941     0,                         /*tp_as_number*/
942     0,                         /*tp_as_sequence*/
943     0,                         /*tp_as_mapping*/
944     0,                         /*tp_hash */
945     0,                         /*tp_call*/
946     0,                         /*tp_str*/
947     0,                         /*tp_getattro*/
948     0,                         /*tp_setattro*/
949     0,                         /*tp_as_buffer*/
950     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
951     "BitstreamWriterPosition", /* tp_doc */
952     0,                         /* tp_traverse */
953     0,                         /* tp_clear */
954     0,                         /* tp_richcompare */
955     0,                         /* tp_weaklistoffset */
956     0,                         /* tp_iter */
957     0,                         /* tp_iternext */
958     0,                         /* tp_methods */
959     0,                         /* tp_members */
960     0,                         /* tp_getset */
961     0,                         /* tp_base */
962     0,                         /* tp_dict */
963     0,                         /* tp_descr_get */
964     0,                         /* tp_descr_set */
965     0,                         /* tp_dictoffset */
966     (initproc)BitstreamWriterPosition_init, /* tp_init */
967     0,                         /* tp_alloc */
968     BitstreamWriterPosition_new, /* tp_new */
969 };
970 
971 /*given a BitstreamReader, format string and list object
972   parses the format from the reader and appends Python values to the list
973   returns 0 on success, 1 on failure (with PyErr set)*/
974 int
975 bitstream_parse(BitstreamReader* stream,
976                 const char* format,
977                 PyObject* values);
978 
979 /*given a BitstreamWriter, format string and PySequence of Python values,
980   writes those values to the writer
981   returns 0 on success, 1 on failure (with PyErr set)*/
982 int
983 bitstream_build(BitstreamWriter* stream,
984                 const char* format,
985                 PyObject* iterator);
986 
987 void
988 BitstreamWriter_callback(uint8_t byte, PyObject *callback);
989