Skip to content

Commit

Permalink
Shift the callback handlers to methods.
Browse files Browse the repository at this point in the history
This removes some of the last standalone functions in the bitstream module.
  • Loading branch information
tuffy committed Aug 18, 2014
1 parent d200a01 commit 6e14965
Show file tree
Hide file tree
Showing 14 changed files with 286 additions and 334 deletions.
283 changes: 118 additions & 165 deletions src/bitstream.c

Large diffs are not rendered by default.

124 changes: 70 additions & 54 deletions src/bitstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ typedef struct BitstreamReader_s {
struct bs_exception* exceptions;
struct br_mark_stack* mark_stacks;

struct bs_callback* callbacks_used;
struct bs_exception* exceptions_used;

/*returns "count" number of unsigned bits from the current stream
Expand Down Expand Up @@ -277,6 +276,33 @@ typedef struct BitstreamReader_s {
void
(*close)(struct BitstreamReader_s* bs);

/*pushes a callback function into the stream
which is called on every byte read*/
void
(*add_callback)(struct BitstreamReader_s* bs,
bs_callback_f callback,
void* data);

/*pushes the given callback onto the callback stack
data from "callback" is copied onto a new internal struct
it does not need to be allocated from the heap*/
void
(*push_callback)(struct BitstreamReader_s* bs,
struct bs_callback* callback);

/*pops the most recently added callback from the stack
if "callback" is not NULL, data from the popped callback
is copied to that struct*/
void
(*pop_callback)(struct BitstreamReader_s* bs,
struct bs_callback* callback);

/*explicitly call all set callbacks as if "byte" had been read
from the input stream*/
void
(*call_callbacks)(struct BitstreamReader_s* bs,
uint8_t byte);

/*pushes the stream's current position onto the given mark stack
all pushed marks should be unmarked once no longer needed*/
Expand Down Expand Up @@ -645,40 +671,25 @@ br_substream_append(struct BitstreamReader_s *stream,
unsigned bytes);


/*unattached, BitstreamReader functions*/


/*adds the given callback to BitstreamReader's callback stack*/
/*bs->add_callback(bs, callback, data) method*/
void
br_add_callback(BitstreamReader *bs, bs_callback_f callback, void *data);

/*explicitly passes "byte" to the set callbacks,
as if the byte were read from the input stream*/

/*bs->push_callback(bs, callback) method*/
void
br_call_callbacks(BitstreamReader *bs, uint8_t byte);
br_push_callback(BitstreamReader *bs, struct bs_callback *callback);

/*removes the most recently added callback, if any
if "callback" is not NULL, the popped callback's data is copied to it
for possible restoration via "br_push_callback"

this is often paired with bs_push_callback in order
to temporarily disable a callback, for example:
/*bs->pop_callback(bs, callback) method*/
void
br_pop_callback(BitstreamReader *bs, struct bs_callback *callback);

br_pop_callback(reader, &saved_callback); //save callback for later
unchecksummed_value = bs->read(bs, 16); //read a value
br_push_callback(reader, &saved_callback); //restore saved callback
*/
#define br_pop_callback(bs, callback) __br_pop_callback((bs), (callback), __FILE__, __LINE__)

/*bs->call_callbacks(bs, byte) method*/
void
__br_pop_callback(BitstreamReader *bs, struct bs_callback *callback,
const char *file, int lineno);
br_call_callbacks(BitstreamReader *bs, uint8_t byte);

/*pushes the given callback back onto the callback stack
note that the data from "callback" is copied onto a new internal struct;
it does not need to be allocated from the heap*/
void
br_push_callback(BitstreamReader *bs, struct bs_callback *callback);


/*Called by the read functions if one attempts to read past
Expand Down Expand Up @@ -779,7 +790,6 @@ typedef struct BitstreamWriter_s {
struct bs_exception* exceptions;
struct bw_mark_stack* mark_stacks;

struct bs_callback* callbacks_used;
struct bs_exception* exceptions_used;

/*writes the given value as "count" number of unsigned bits
Expand Down Expand Up @@ -956,6 +966,33 @@ typedef struct BitstreamWriter_s {
void
(*close)(struct BitstreamWriter_s* bs);

/*pushes a callback function into the stream
which is called on every byte read*/
void
(*add_callback)(struct BitstreamWriter_s* bs,
bs_callback_f callback,
void* data);

/*pushes the given callback onto the callback stack
data from "callback" is copied onto a new internal struct
it does not need to be allocated from the heap*/
void
(*push_callback)(struct BitstreamWriter_s* bs,
struct bs_callback* callback);

/*pops the most recently added callback from the stack
if "callback" is not NULL, data from the popped callback
is copied to that struct*/
void
(*pop_callback)(struct BitstreamWriter_s* bs,
struct bs_callback* callback);

/*explicitly call all set callbacks as if "byte" had been read
from the input stream*/
void
(*call_callbacks)(struct BitstreamWriter_s* bs,
uint8_t byte);

/*pushes the stream's current position onto the given mark stack
all pushed marks should be unmarked once no longer needed
Expand Down Expand Up @@ -1326,40 +1363,19 @@ bw_unmark_r_a(BitstreamWriter *bs, int mark_id);
/*unattached, BitstreamWriter functions*/


/*adds a callback function, which is called on every byte written
the function's arguments are the written byte and a generic
pointer to some other data structure
*/
/*bs->add_callback(bs, callback, data) method*/
void
bw_add_callback(BitstreamWriter* bs, bs_callback_f callback, void *data);

/*removes the most recently added callback, if any
if "callback" is not NULL, the popped callback's data is copied to it
for possible restoration via "bw_push_callback"
this is often paired with bs_push_callback in order
to temporarily disable a callback, for example:
bw_pop_callback(writer, &saved_callback); //save callback for later
bs->write(bs, 16, 0xAB); //write a value
bw_push_callback(writer, &saved_callback); //restore saved callback
*/

#define bw_pop_callback(bs, callback) __bw_pop_callback((bs), (callback), __FILE__, __LINE__)
bw_add_callback(BitstreamWriter *bs, bs_callback_f callback, void *data);

/*bs->push_callback(bs, callback) method*/
void
__bw_pop_callback(BitstreamWriter* bs, struct bs_callback* callback,
const char *file, int lineno);
bw_push_callback(BitstreamWriter *bs, struct bs_callback *callback);

/*pushes the given callback back onto the callback stack
note that the data from "callback" is copied onto a new internal struct;
it does not need to be allocated from the heap*/
/*bs->pop_callback(bs, callback) method*/
void
bw_push_callback(BitstreamWriter* bs, struct bs_callback* callback);
bw_pop_callback(BitstreamWriter *bs, struct bs_callback *callback);

/*explicitly passes "byte" to the set callbacks,
as if the byte were written to the output stream*/
/*bs->call_callbacks(bs, byte) method*/
void
bw_call_callbacks(BitstreamWriter *bs, uint8_t byte);

Expand Down
40 changes: 20 additions & 20 deletions src/decoders/flac.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,13 +211,13 @@ FlacDecoder_read(decoders_FlacDecoder* self, PyObject *args)

if (!setjmp(*br_try(self->bitstream))) {
/*add callback for CRC16 calculation*/
br_add_callback(self->bitstream, (bs_callback_f)flac_crc16, &crc16);
self->bitstream->add_callback(self->bitstream, (bs_callback_f)flac_crc16, &crc16);

/*read frame header*/
if ((error = flacdec_read_frame_header(self->bitstream,
&(self->streaminfo),
&frame_header)) != OK) {
br_pop_callback(self->bitstream, NULL);
self->bitstream->pop_callback(self->bitstream, NULL);
PyErr_SetString(PyExc_ValueError, FlacDecoder_strerror(error));
br_etry(self->bitstream);
return NULL;
Expand All @@ -235,7 +235,7 @@ FlacDecoder_read(decoders_FlacDecoder* self, PyObject *args)
flacdec_subframe_bits_per_sample(&frame_header,
channel),
self->subframe_data->append(self->subframe_data))) != OK) {
br_pop_callback(self->bitstream, NULL);
self->bitstream->pop_callback(self->bitstream, NULL);
PyErr_SetString(PyExc_ValueError, FlacDecoder_strerror(error));
br_etry(self->bitstream);
return NULL;
Expand All @@ -249,7 +249,7 @@ FlacDecoder_read(decoders_FlacDecoder* self, PyObject *args)
/*check CRC-16*/
self->bitstream->byte_align(self->bitstream);
self->bitstream->read(self->bitstream, 16);
br_pop_callback(self->bitstream, NULL);
self->bitstream->pop_callback(self->bitstream, NULL);
if (crc16 != 0) {
PyErr_SetString(PyExc_ValueError, "invalid checksum in frame");
br_etry(self->bitstream);
Expand All @@ -260,7 +260,7 @@ FlacDecoder_read(decoders_FlacDecoder* self, PyObject *args)
self->remaining_samples -= frame_header.block_size;
} else {
/*handle I/O error during read*/
br_pop_callback(self->bitstream, NULL);
self->bitstream->pop_callback(self->bitstream, NULL);
PyErr_SetString(PyExc_IOError, "EOF reading frame");
br_etry(self->bitstream);
return NULL;
Expand Down Expand Up @@ -375,9 +375,9 @@ FlacDecoder_offsets(decoders_FlacDecoder* self, PyObject *args)
unsigned samples;
unsigned long long offset;

br_add_callback(self->bitstream,
(bs_callback_f)increment_offset,
&total_offset);
self->bitstream->add_callback(self->bitstream,
(bs_callback_f)increment_offset,
&total_offset);

while (self->remaining_samples > 0) {
self->subframe_data->reset(self->subframe_data);
Expand Down Expand Up @@ -433,13 +433,13 @@ FlacDecoder_offsets(decoders_FlacDecoder* self, PyObject *args)
}

self->stream_finalized = 1;
br_pop_callback(self->bitstream, NULL);
self->bitstream->pop_callback(self->bitstream, NULL);

return offsets;
error:
Py_XDECREF(offsets);
br_etry(self->bitstream);
br_pop_callback(self->bitstream, NULL);
self->bitstream->pop_callback(self->bitstream, NULL);

return NULL;
}
Expand Down Expand Up @@ -718,18 +718,18 @@ flacdec_read_frame_header(BitstreamReader *bitstream,
uint8_t crc8 = 0;

if (!setjmp(*br_try(bitstream))) {
br_add_callback(bitstream, (bs_callback_f)flac_crc8, &crc8);
bitstream->add_callback(bitstream, (bs_callback_f)flac_crc8, &crc8);

/*read and verify sync code*/
if (bitstream->read(bitstream, 14) != 0x3FFE) {
br_pop_callback(bitstream, NULL);
bitstream->pop_callback(bitstream, NULL);
br_etry(bitstream);
return ERR_INVALID_SYNC_CODE;
}

/*read and verify reserved bit*/
if (bitstream->read(bitstream, 1) != 0) {
br_pop_callback(bitstream, NULL);
bitstream->pop_callback(bitstream, NULL);
br_etry(bitstream);
return ERR_INVALID_RESERVED_BIT;
}
Expand Down Expand Up @@ -820,7 +820,7 @@ flacdec_read_frame_header(BitstreamReader *bitstream,
bitstream->read(bitstream, 8);

/*no more I/O after this point*/
br_pop_callback(bitstream, NULL);
bitstream->pop_callback(bitstream, NULL);
br_etry(bitstream);

if (crc8 != 0)
Expand All @@ -845,7 +845,7 @@ flacdec_read_frame_header(BitstreamReader *bitstream,
return OK;
} else {
/*push read error to calling function*/
br_pop_callback(bitstream, NULL);
bitstream->pop_callback(bitstream, NULL);
br_etry(bitstream);
br_abort(bitstream);
return OK; /*won't get here*/
Expand Down Expand Up @@ -1416,13 +1416,13 @@ int main(int argc, char* argv[]) {
uint16_t crc16 = 0;

/*add callback for CRC16 calculation*/
br_add_callback(reader, (bs_callback_f)flac_crc16, &crc16);
reader->add_callback(reader, (bs_callback_f)flac_crc16, &crc16);

/*read frame header*/
if ((error = flacdec_read_frame_header(reader,
&streaminfo,
&frame_header)) != OK) {
br_pop_callback(reader, NULL);
reader->pop_callback(reader, NULL);
br_etry(reader);
fprintf(stderr, "*** Error: %s\n", FlacDecoder_strerror(error));
goto error;
Expand All @@ -1440,7 +1440,7 @@ int main(int argc, char* argv[]) {
flacdec_subframe_bits_per_sample(&frame_header,
channel),
subframe_data->append(subframe_data))) != OK) {
br_pop_callback(reader, NULL);
reader->pop_callback(reader, NULL);
br_etry(reader);
fprintf(stderr, "*** Error: %s\n",
FlacDecoder_strerror(error));
Expand All @@ -1455,7 +1455,7 @@ int main(int argc, char* argv[]) {
/*check CRC-16*/
reader->byte_align(reader);
reader->read(reader, 16);
br_pop_callback(reader, NULL);
reader->pop_callback(reader, NULL);
if (crc16 != 0) {
br_etry(reader);
fprintf(stderr, "*** Error: invalid checksum in frame\n");
Expand All @@ -1468,7 +1468,7 @@ int main(int argc, char* argv[]) {
br_etry(reader);
} else {
/*handle I/O error during read*/
br_pop_callback(reader, NULL);
reader->pop_callback(reader, NULL);
br_etry(reader);
fprintf(stderr, "*** I/O Error reading frame\n");
goto error;
Expand Down
8 changes: 4 additions & 4 deletions src/decoders/mlp.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,10 @@ read_mlp_frame(MLPDecoder* decoder,
uint8_t parity;
uint8_t CRC8;

br_add_callback(bs, mlp_checkdata_callback, &checkdata);
bs->add_callback(bs, mlp_checkdata_callback, &checkdata);
bs->substream_append(bs, decoder->substream_reader,
substream0->info.substream_end - 2);
br_pop_callback(bs, NULL);
bs->pop_callback(bs, NULL);

parity = (uint8_t)bs->read(bs, 8);
if ((parity ^ checkdata.parity) != 0xA9) {
Expand Down Expand Up @@ -334,12 +334,12 @@ read_mlp_frame(MLPDecoder* decoder,
unsigned CRC8;
unsigned parity;

br_add_callback(bs, mlp_checkdata_callback, &checkdata);
bs->add_callback(bs, mlp_checkdata_callback, &checkdata);
bs->substream_append(bs, decoder->substream_reader,
substream1->info.substream_end -
substream0->info.substream_end -
2);
br_pop_callback(bs, NULL);
bs->pop_callback(bs, NULL);

parity = (uint8_t)bs->read(bs, 8);
if ((parity ^ checkdata.parity) != 0xA9) {
Expand Down
4 changes: 2 additions & 2 deletions src/decoders/oggflac.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ OggFlacDecoder_init(decoders_OggFlacDecoder *self,
audiotools__MD5Init(&(self->md5));

/*add callback for CRC16 calculation*/
br_add_callback(self->packet, (bs_callback_f)flac_crc16, &(self->crc16));
self->packet->add_callback(self->packet, (bs_callback_f)flac_crc16, &(self->crc16));

/*setup a framelist generator function*/
if ((self->audiotools_pcm = open_audiotools_pcm()) == NULL)
Expand Down Expand Up @@ -466,7 +466,7 @@ int main(int argc, char* argv[]) {
audiotools__MD5Init(&md5);

/*add callback for CRC16 calculation*/
br_add_callback(packet, (bs_callback_f)flac_crc16, &crc16);
packet->add_callback(packet, (bs_callback_f)flac_crc16, &crc16);

/*decode the next FrameList from the stream*/
br_substream_reset(packet);
Expand Down
Loading

0 comments on commit 6e14965

Please sign in to comment.