smart ot::file handle

This commit is contained in:
Frédéric Mangano-Tarumi 2018-11-24 11:32:17 -05:00
parent bfa46273b9
commit d1299360de
4 changed files with 21 additions and 30 deletions

View File

@ -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;

View File

@ -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

View File

@ -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()))

View File

@ -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)