file_util: Remove goto usages from Copy()
We can just leverage std::unique_ptr to automatically close these for us in error cases instead of jumping to the end of the function to call fclose on them.
This commit is contained in:
parent
4a3c4f5f67
commit
d3a52e45e3
|
@ -2,6 +2,8 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <memory>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/common_paths.h"
|
#include "common/common_paths.h"
|
||||||
|
@ -273,14 +275,10 @@ bool Copy(const std::string& srcFilename, const std::string& destFilename) {
|
||||||
GetLastErrorMsg());
|
GetLastErrorMsg());
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
|
using CFilePointer = std::unique_ptr<FILE, decltype(&std::fclose)>;
|
||||||
// buffer size
|
|
||||||
#define BSIZE 1024
|
|
||||||
|
|
||||||
char buffer[BSIZE];
|
|
||||||
|
|
||||||
// Open input file
|
// Open input file
|
||||||
FILE* input = fopen(srcFilename.c_str(), "rb");
|
CFilePointer input{fopen(srcFilename.c_str(), "rb"), std::fclose};
|
||||||
if (!input) {
|
if (!input) {
|
||||||
LOG_ERROR(Common_Filesystem, "opening input failed {} --> {}: {}", srcFilename,
|
LOG_ERROR(Common_Filesystem, "opening input failed {} --> {}: {}", srcFilename,
|
||||||
destFilename, GetLastErrorMsg());
|
destFilename, GetLastErrorMsg());
|
||||||
|
@ -288,44 +286,36 @@ bool Copy(const std::string& srcFilename, const std::string& destFilename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// open output file
|
// open output file
|
||||||
FILE* output = fopen(destFilename.c_str(), "wb");
|
CFilePointer output{fopen(destFilename.c_str(), "wb"), std::fclose};
|
||||||
if (!output) {
|
if (!output) {
|
||||||
fclose(input);
|
|
||||||
LOG_ERROR(Common_Filesystem, "opening output failed {} --> {}: {}", srcFilename,
|
LOG_ERROR(Common_Filesystem, "opening output failed {} --> {}: {}", srcFilename,
|
||||||
destFilename, GetLastErrorMsg());
|
destFilename, GetLastErrorMsg());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy loop
|
// copy loop
|
||||||
while (!feof(input)) {
|
std::array<char, 1024> buffer;
|
||||||
|
while (!feof(input.get())) {
|
||||||
// read input
|
// read input
|
||||||
size_t rnum = fread(buffer, sizeof(char), BSIZE, input);
|
size_t rnum = fread(buffer.data(), sizeof(char), buffer.size(), input.get());
|
||||||
if (rnum != BSIZE) {
|
if (rnum != buffer.size()) {
|
||||||
if (ferror(input) != 0) {
|
if (ferror(input.get()) != 0) {
|
||||||
LOG_ERROR(Common_Filesystem, "failed reading from source, {} --> {}: {}",
|
LOG_ERROR(Common_Filesystem, "failed reading from source, {} --> {}: {}",
|
||||||
srcFilename, destFilename, GetLastErrorMsg());
|
srcFilename, destFilename, GetLastErrorMsg());
|
||||||
goto bail;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// write output
|
// write output
|
||||||
size_t wnum = fwrite(buffer, sizeof(char), rnum, output);
|
size_t wnum = fwrite(buffer.data(), sizeof(char), rnum, output.get());
|
||||||
if (wnum != rnum) {
|
if (wnum != rnum) {
|
||||||
LOG_ERROR(Common_Filesystem, "failed writing to output, {} --> {}: {}", srcFilename,
|
LOG_ERROR(Common_Filesystem, "failed writing to output, {} --> {}: {}", srcFilename,
|
||||||
destFilename, GetLastErrorMsg());
|
destFilename, GetLastErrorMsg());
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// close files
|
|
||||||
fclose(input);
|
|
||||||
fclose(output);
|
|
||||||
return true;
|
|
||||||
bail:
|
|
||||||
if (input)
|
|
||||||
fclose(input);
|
|
||||||
if (output)
|
|
||||||
fclose(output);
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in New Issue