diff --git a/src/ogg.cc b/src/ogg.cc index 76e6cf5..348bf67 100644 --- a/src/ogg.cc +++ b/src/ogg.cc @@ -14,6 +14,25 @@ ot::ogg_reader::~ogg_reader() ogg_stream_clear(&stream); } +ot::status ot::ogg_reader::read_page() +{ + while (ogg_sync_pageout(&sync, &page) != 1) { + if (feof(file)) + return status::end_of_file; + char* buf = ogg_sync_buffer(&sync, 65536); + if (buf == nullptr) + return status::libogg_error; + size_t len = fread(buf, 1, 65536, file); + if (ferror(file)) + return status::standard_error; + if (ogg_sync_wrote(&sync, len) != 0) + return status::libogg_error; + if (ogg_sync_check(&sync) != 0) + return status::libogg_error; + } + return status::ok; +} + ot::ogg_writer::ogg_writer() { memset(&stream, 0, sizeof(stream)); diff --git a/src/opustags.cc b/src/opustags.cc index f89504e..d89103b 100644 --- a/src/opustags.cc +++ b/src/opustags.cc @@ -193,29 +193,20 @@ int main(int argc, char **argv){ } } ot::opus_tags tags; - char *buf; - size_t len; const char *error = NULL; int packet_count = -1; while(error == NULL){ - // Read until we complete a page. - if(ogg_sync_pageout(&reader.sync, &reader.page) != 1){ - if(feof(reader.file)) - break; - buf = ogg_sync_buffer(&reader.sync, 65536); - if(buf == NULL){ - error = "ogg_sync_buffer: out of memory"; - break; - } - len = fread(buf, 1, 65536, reader.file); - if(ferror(reader.file)) + // Read the next page. + ot::status rc = reader.read_page(); + if (rc == ot::status::end_of_file) { + break; + } else if (rc != ot::status::ok) { + if (rc == ot::status::standard_error) error = strerror(errno); - ogg_sync_wrote(&reader.sync, len); - if(ogg_sync_check(&reader.sync) != 0) - error = "ogg_sync_check: internal error"; - continue; + else + error = "error reading the next ogg page"; + break; } - // We got a page. // Short-circuit when the relevant packets have been read. if(packet_count >= 2 && writer.file){ if(ot::write_page(&reader.page, writer.file) == -1){ diff --git a/src/opustags.h b/src/opustags.h index 51e8725..f00d82b 100644 --- a/src/opustags.h +++ b/src/opustags.h @@ -69,6 +69,8 @@ struct ogg_reader { /** * Initialize the sync state and zero-initialize the stream. You'll need to initialize the * stream yourself once you have the serialno. + * + * \todo Take a FILE*. */ ogg_reader(); /** @@ -78,6 +80,12 @@ struct ogg_reader { * The input file is not closed. */ ~ogg_reader(); + /** + * Read the next page from the input file. The result, provided the status is #status::ok, + * is available in the #page field, is owned by the Ogg reader, and is valid until the next + * call to #read_page. Make sure you also check #status::end_of_file. + */ + status read_page(); /** * The file is our source of binary data. It is not integrated to libogg, so we need to * handle it ourselves.