From d1299360de4fe9816b73a56db89e053ac1754912 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Mangano-Tarumi?= <fmang@mg0.fr> Date: Sat, 24 Nov 2018 11:32:17 -0500 Subject: [PATCH] smart ot::file handle --- src/cli.cc | 16 +++++++--------- src/opustags.h | 13 +++++-------- t/cli.cc | 2 +- t/ogg.cc | 20 ++++++++------------ 4 files changed, 21 insertions(+), 30 deletions(-) diff --git a/src/cli.cc b/src/cli.cc index ef62182..d83474a 100644 --- a/src/cli.cc +++ b/src/cli.cc @@ -293,29 +293,27 @@ ot::status ot::run(ot::options& opt) if (!opt.path_out.empty() && same_file(opt.path_in, opt.path_out)) return {ot::st::fatal_error, "Input and output files are the same"}; - std::unique_ptr<FILE, decltype(&fclose)> input(nullptr, &fclose); + ot::file input; if (opt.path_in == "-") { - input.reset(stdin); + input = stdin; } else { - FILE* input_file = fopen(opt.path_in.c_str(), "r"); - if (input_file == nullptr) + input = fopen(opt.path_in.c_str(), "r"); + if (input == nullptr) return {ot::st::standard_error, "could not open '" + opt.path_in + "' for reading: " + strerror(errno)}; - input.reset(input_file); } - std::unique_ptr<FILE, decltype(&fclose)> output(nullptr, &fclose); + ot::file output; if (opt.path_out == "-") { output.reset(stdout); } else if (!opt.path_out.empty()) { if (!opt.overwrite && access(opt.path_out.c_str(), F_OK) == 0) return {ot::st::fatal_error, "'" + opt.path_out + "' already exists (use -y to overwrite)"}; - FILE* output_file = fopen(opt.path_out.c_str(), "w"); - if (output_file == nullptr) + output = fopen(opt.path_out.c_str(), "w"); + if (output == nullptr) return {ot::st::standard_error, "could not open '" + opt.path_out + "' for writing: " + strerror(errno)}; - output.reset(output_file); } ot::status rc; diff --git a/src/opustags.h b/src/opustags.h index b91a836..53788b7 100644 --- a/src/opustags.h +++ b/src/opustags.h @@ -85,16 +85,13 @@ struct status { }; /** - * Call a fopen-like function that returns a FILE* such that the returned pointer is smart and calls - * fclose on destruction. + * Smart auto-closing FILE* handle. * - * Example : `auto my_file = ot::make_file(fopen, "foo.txt", "r");` + * It implictly converts from an already opened FILE*. */ -template <typename Opener, typename... Args> -std::unique_ptr<FILE, decltype(&fclose)> make_file(Opener&& f, Args&&... args) -{ - return {f(std::forward<Args>(args)...), &fclose}; -} +struct file : std::unique_ptr<FILE, decltype(&fclose)> { + file(FILE* f = nullptr) : std::unique_ptr<FILE, decltype(&fclose)>(f, &fclose) {} +}; /***********************************************************************************************//** * \defgroup ogg Ogg diff --git a/t/cli.cc b/t/cli.cc index 74bd4d4..2809260 100644 --- a/t/cli.cc +++ b/t/cli.cc @@ -10,7 +10,7 @@ Artist=Y void check_read_comments() { - auto input = ot::make_file(fmemopen, const_cast<char*>(user_comments), strlen(user_comments), "r"); + ot::file input = fmemopen(const_cast<char*>(user_comments), strlen(user_comments), "r"); auto comments = ot::read_comments(input.get()); auto&& expected = {"TITLE=a b c", "ARTIST=X", "Artist=Y"}; if (!std::equal(comments.begin(), comments.end(), expected.begin(), expected.end())) diff --git a/t/ogg.cc b/t/ogg.cc index 21a4384..a55be2f 100644 --- a/t/ogg.cc +++ b/t/ogg.cc @@ -3,10 +3,9 @@ static void check_ref_ogg() { - FILE* input_file = fopen("gobble.opus", "r"); - if (input_file == nullptr) + ot::file input = fopen("gobble.opus", "r"); + if (input == nullptr) throw failure("could not open gobble.opus"); - std::unique_ptr<FILE, decltype(&fclose)> input(input_file, &fclose); ot::ogg_reader reader(input.get()); @@ -69,11 +68,10 @@ static void check_memory_ogg() size_t my_ogg_size; ot::status rc; - FILE* output_mem = fmemopen(my_ogg.data(), my_ogg.size(), "w"); - if (output_mem == nullptr) - throw failure("could not open the output stream"); - std::unique_ptr<FILE, decltype(&fclose)> output(output_mem, &fclose); { + ot::file output = fmemopen(my_ogg.data(), my_ogg.size(), "w"); + if (output == nullptr) + throw failure("could not open the output stream"); ot::ogg_writer writer(output.get()); rc = writer.prepare_stream(1234); if (rc != ot::st::ok) @@ -100,13 +98,11 @@ static void check_memory_ogg() if (my_ogg_size != 73) throw failure("unexpected output size"); } - output.reset(); - FILE* input_mem = fmemopen(my_ogg.data(), my_ogg_size, "r"); - if (input_mem == nullptr) - throw failure("could not open the input stream"); - std::unique_ptr<FILE, decltype(&fclose)> input(input_mem, &fclose); { + ot::file input = fmemopen(my_ogg.data(), my_ogg_size, "r"); + if (input == nullptr) + throw failure("could not open the input stream"); ot::ogg_reader reader(input.get()); rc = reader.read_page(); if (rc != ot::st::ok)