mirror of
https://github.com/fmang/opustags.git
synced 2024-11-10 07:27:22 +01:00
review the overall code documentation
This commit is contained in:
parent
8949094203
commit
407c12c7ac
45
src/cli.cc
45
src/cli.cc
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* \file src/cli.cc
|
||||
* \ingroup cli
|
||||
*
|
||||
* Provide all the features of the opustags executable from a C++ API. The main point of separating
|
||||
* this module from the main one is to allow easy testing.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <opustags.h>
|
||||
|
||||
@ -41,21 +49,6 @@ static struct option getopt_options[] = {
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
/**
|
||||
* Process the command-line arguments.
|
||||
*
|
||||
* This function does not perform I/O related validations, but checks the consistency of its
|
||||
* arguments.
|
||||
*
|
||||
* It returns one of :
|
||||
* - #ot::st::ok, meaning the process may continue normally.
|
||||
* - #ot::st::exit_now, meaning there is nothing to do and process should exit successfully.
|
||||
* This happens when all the user wants is see the help or usage.
|
||||
* - #ot::st::bad_arguments, meaning the arguments were invalid and the process should exit with
|
||||
* an error.
|
||||
*
|
||||
* Help messages are written on standard output, and error messages on standard error.
|
||||
*/
|
||||
ot::status ot::process_options(int argc, char** argv, ot::options& opt)
|
||||
{
|
||||
if (argc == 1) {
|
||||
@ -149,14 +142,6 @@ ot::status ot::process_options(int argc, char** argv, ot::options& opt)
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the tags on stdout.
|
||||
*
|
||||
* Print all the comments, separated by line breaks. Since a comment may
|
||||
* contain line breaks, this output is not completely reliable, but it fits
|
||||
* most cases.
|
||||
*
|
||||
* The output generated is meant to be parseable by #ot::read_tags.
|
||||
*
|
||||
* \todo Escape new lines.
|
||||
*/
|
||||
void ot::print_comments(const std::list<std::string>& comments, FILE* output)
|
||||
@ -168,9 +153,7 @@ void ot::print_comments(const std::list<std::string>& comments, FILE* output)
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the comments outputted by #ot::print_comments.
|
||||
*
|
||||
* \todo Use an std::istream or getline. Lift the 16 KiB limitation and whatever's hardcoded here.
|
||||
* \todo Use getline. Lift the 16 KiB limitation and whatever's hardcoded here.
|
||||
*/
|
||||
std::list<std::string> ot::read_comments(FILE* input)
|
||||
{
|
||||
@ -236,10 +219,6 @@ static ot::status process_tags(const ogg_packet& packet, const ot::options& opt,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Main loop of opustags. Read the packets from the reader, and forwards them to the writer.
|
||||
* Transform the OpusTags packet on the fly.
|
||||
*/
|
||||
ot::status ot::process(ogg_reader& reader, ogg_writer* writer, const ot::options &opt)
|
||||
{
|
||||
int packet_count = 0;
|
||||
@ -307,12 +286,6 @@ static bool same_file(const std::string& path_in, const std::string& path_out)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the input and output streams, then call #ot::process.
|
||||
*
|
||||
* This is the main entry point to the opustags program, and pretty much the same as calling
|
||||
* opustags from the command-line.
|
||||
*/
|
||||
ot::status ot::run(ot::options& opt)
|
||||
{
|
||||
if (!opt.path_out.empty() && same_file(opt.path_in, opt.path_out))
|
||||
|
@ -1,6 +1,11 @@
|
||||
/**
|
||||
* \file src/ogg.c
|
||||
* \ingroup ogg
|
||||
*
|
||||
* High-level interface for libogg.
|
||||
*
|
||||
* This module is not meant to be a complete libogg wrapper, but rather a convenient and highly
|
||||
* specialized layer above libogg and stdio.
|
||||
*/
|
||||
|
||||
#include "opustags.h"
|
||||
|
@ -1,3 +1,10 @@
|
||||
/**
|
||||
* \file src/opustags.cc
|
||||
* \brief Main function for opustags.
|
||||
*
|
||||
* See opustags.h for the program's documentation.
|
||||
*/
|
||||
|
||||
#include <opustags.h>
|
||||
|
||||
/**
|
||||
|
171
src/opustags.h
171
src/opustags.h
@ -1,6 +1,24 @@
|
||||
/**
|
||||
* \file src/opustags.h
|
||||
* \brief Interface of all the submodules of opustags.
|
||||
*
|
||||
* Welcome to opustags!
|
||||
*
|
||||
* Let's have a quick tour around. The project is split into the following modules:
|
||||
*
|
||||
* - The ogg module reads and writes Ogg files, letting you manipulate Ogg pages and packets.
|
||||
* - The opus module parses the contents of Ogg packets according to the Opus specifications.
|
||||
* - The cli module implements the main logic of the program.
|
||||
* - The opustags module contains the main function, which is a simple wrapper around cli.
|
||||
*
|
||||
* Each module is implemented in its eponymous .cc file. Their interfaces are all defined and
|
||||
* documented together in this header file. Look into the .cc files for implementation-specific
|
||||
* details.
|
||||
*
|
||||
* To understand how this program works, you need to know what an Ogg files is made of, in
|
||||
* particular the streams, pages, and packets. You hardly need any knowledge of the actual Opus
|
||||
* audio codec, but need the RFC 7845 "Ogg Encapsulation for the Opus Audio Codec" that defines the
|
||||
* format of the header packets that are essential to opustags.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ogg/ogg.h>
|
||||
@ -16,7 +34,12 @@
|
||||
namespace ot {
|
||||
|
||||
/**
|
||||
* Possible return status.
|
||||
* Possible return status code, ranging from errors to special statuses. They are usually
|
||||
* accompanied with a message with the #status structure.
|
||||
*
|
||||
* Functions that return non-ok status codes to signal special conditions like #end_of_stream should
|
||||
* have it explictly mentionned in their documentation. By default, a non-ok status should be
|
||||
* handled like an error.
|
||||
*
|
||||
* The cut error family means that the end of packet was reached when attempting to read the
|
||||
* overflowing value. For example, cut_comment_count means that after reading the vendor string,
|
||||
@ -47,10 +70,11 @@ enum class st {
|
||||
};
|
||||
|
||||
/**
|
||||
* Wraps a status code with an optional message. It is implictly converted from and to a
|
||||
* Wraps a status code with an optional message. It is implictly converted to and from a
|
||||
* #status_code.
|
||||
*
|
||||
* All the error statuses should be accompanied with a relevant error message.
|
||||
* All the statuses except #st::ok should be accompanied with a relevant error message, in case it
|
||||
* propagates back to the main function and is shown to the user.
|
||||
*/
|
||||
struct status {
|
||||
status(st code = st::ok) : code(code) {}
|
||||
@ -60,14 +84,8 @@ struct status {
|
||||
std::string message;
|
||||
};
|
||||
|
||||
/**
|
||||
/***********************************************************************************************//**
|
||||
* \defgroup ogg Ogg
|
||||
*
|
||||
* High-level interface for libogg.
|
||||
*
|
||||
* This module is not meant to be a complete libogg wrapper, but rather a convenient and highly
|
||||
* specialized layer above libogg and stdio.
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
@ -251,28 +269,31 @@ private:
|
||||
|
||||
/** \} */
|
||||
|
||||
/**
|
||||
/***********************************************************************************************//**
|
||||
* \defgroup opus Opus
|
||||
* \brief Opus packet decoding and recoding.
|
||||
*
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represent all the data in an OpusTags packet.
|
||||
* Faithfully represent *all* the data in an OpusTags packet, exactly as they will be written in the
|
||||
* final stream, disregarding the current system locale or anything else.
|
||||
*
|
||||
* The vendor and comment strings are expected to contain valid UTF-8, but we should keep their
|
||||
* values intact even if the string is not UTF-8 clean, or encoded in any other way.
|
||||
*/
|
||||
struct opus_tags {
|
||||
/**
|
||||
* OpusTags packets begin with a vendor string, meant to identify the
|
||||
* implementation of the encoder. It is an arbitrary UTF-8 string.
|
||||
* OpusTags packets begin with a vendor string, meant to identify the implementation of the
|
||||
* encoder. It should be an arbitrary UTF-8 string.
|
||||
*/
|
||||
std::string vendor;
|
||||
/**
|
||||
* Comments. These are a list of string following the NAME=Value format.
|
||||
* A comment may also be called a field, or a tag.
|
||||
* Comments. These are a list of string following the NAME=Value format. A comment may also
|
||||
* be called a field, or a tag.
|
||||
*
|
||||
* The field name in vorbis comment is case-insensitive and ASCII,
|
||||
* while the value can be any valid UTF-8 string.
|
||||
* The field name in vorbis comment is case-insensitive and ASCII, while the value can be
|
||||
* any valid UTF-8 string. The specification is not too clear for Opus, but let's assume
|
||||
* it's the same.
|
||||
*/
|
||||
std::list<std::string> comments;
|
||||
/**
|
||||
@ -315,35 +336,131 @@ void delete_comments(opus_tags& tags, const char* field_name);
|
||||
|
||||
/** \} */
|
||||
|
||||
/**
|
||||
/***********************************************************************************************//**
|
||||
* \defgroup cli Command-Line Interface
|
||||
* \{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Structured representation of the arguments to opustags.
|
||||
*/
|
||||
struct options {
|
||||
/**
|
||||
* Path to the input file. It cannot be empty. The special "-" string means stdin.
|
||||
*
|
||||
* This is the mandatory non-flagged parameter.
|
||||
*/
|
||||
std::string path_in;
|
||||
/**
|
||||
* Path to the optional file. The special "-" string means stdout. When empty, opustags runs
|
||||
* in read-only mode.
|
||||
*
|
||||
* Option: --output
|
||||
*/
|
||||
std::string path_out;
|
||||
/**
|
||||
* If null, in-place editing is disabled.
|
||||
* Otherwise, it contains the suffix to add to the file name.
|
||||
* If null, in-place editing is disabled. Otherwise, it points to the suffix to add to the
|
||||
* file name.
|
||||
*
|
||||
* Option: --in-place
|
||||
*/
|
||||
const char* inplace = nullptr;
|
||||
/**
|
||||
* List of field names to delete. `{"ARTIST"}` will delete *all* the comments `ARTIST=*`. It
|
||||
* is currently case-sensitive. When #delete_all is true, it becomes meaningless.
|
||||
*
|
||||
* #to_add takes precedence over #to_delete, so if the same comment appears in both lists,
|
||||
* the one in #to_delete applies only to the previously existing tags.
|
||||
*
|
||||
* \todo Consider making it case-insensitive.
|
||||
* \todo Allow values like `ARTIST=x` to delete only the ARTIST comment whose value is x.
|
||||
*
|
||||
* Option: --delete, --set
|
||||
*/
|
||||
const char *inplace = nullptr;
|
||||
std::vector<std::string> to_add;
|
||||
std::vector<std::string> to_delete;
|
||||
/**
|
||||
* List of comments to add, in the current system encoding. For exemple `TITLE=a b c`. They
|
||||
* must be valid.
|
||||
*
|
||||
* Options: --add, --set, --set-all
|
||||
*/
|
||||
std::vector<std::string> to_add;
|
||||
/**
|
||||
* Delete all the existing comments.
|
||||
*
|
||||
* Option: --delete-all
|
||||
*/
|
||||
bool delete_all = false;
|
||||
/**
|
||||
* Replace the previous comments by the ones supplied by the user.
|
||||
*
|
||||
* Read a list of comments from stdin and populate #to_add. Implies #delete_all. Further
|
||||
* comments may be added with the --add option.
|
||||
*
|
||||
* Option: --set-all
|
||||
*/
|
||||
bool set_all = false;
|
||||
/**
|
||||
* By default, opustags won't overwrite the output file if it already exists.
|
||||
*
|
||||
* Option: --overwrite
|
||||
*/
|
||||
bool overwrite = false;
|
||||
/**
|
||||
* When true, opustags prints a detailed help and exits. All the other options are ignored.
|
||||
*
|
||||
* Option: --help
|
||||
*/
|
||||
bool print_help = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Process the command-line arguments.
|
||||
*
|
||||
* This function does not perform I/O related validations, but checks the consistency of its
|
||||
* arguments.
|
||||
*
|
||||
* It returns one of :
|
||||
* - #ot::st::ok, meaning the process may continue normally.
|
||||
* - #ot::st::exit_now, meaning there is nothing to do and process should exit successfully.
|
||||
* This happens when all the user wants is see the help or usage.
|
||||
* - #ot::st::bad_arguments, meaning the arguments were invalid and the process should exit with
|
||||
* an error.
|
||||
*
|
||||
* Help messages are written on standard output, and error messages on standard error.
|
||||
*/
|
||||
status process_options(int argc, char** argv, options& opt);
|
||||
|
||||
/**
|
||||
* Print all the comments, separated by line breaks. Since a comment may
|
||||
* contain line breaks, this output is not completely reliable, but it fits
|
||||
* most cases.
|
||||
*
|
||||
* The output generated is meant to be parseable by #ot::read_tags.
|
||||
*/
|
||||
void print_comments(const std::list<std::string>& comments, FILE* output);
|
||||
|
||||
/**
|
||||
* Parse the comments outputted by #ot::print_comments.
|
||||
*/
|
||||
std::list<std::string> read_comments(FILE* input);
|
||||
|
||||
status run(options& opt);
|
||||
/**
|
||||
* Main loop of opustags. Read the packets from the reader, and forwards them to the writer.
|
||||
* Transform the OpusTags packet on the fly.
|
||||
*
|
||||
* The writer is optional. When writer is nullptr, opustags runs in read-only mode.
|
||||
*/
|
||||
status process(ogg_reader& reader, ogg_writer* writer, const options &opt);
|
||||
|
||||
/**
|
||||
* Open the input and output streams, then call #ot::process.
|
||||
*
|
||||
* This is the main entry point to the opustags program, and pretty much the same as calling
|
||||
* opustags from the command-line.
|
||||
*/
|
||||
status run(options& opt);
|
||||
|
||||
/** \} */
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user