scoped deref mem utils intro proposal.

trying out in two cases for now.
This commit is contained in:
David Carlier 2022-03-06 19:02:15 +00:00
parent 854c31be9d
commit 18018a5cc1
3 changed files with 56 additions and 34 deletions

View File

@ -31,6 +31,7 @@
#include "utils/extract_mobile_assets.hpp" #include "utils/extract_mobile_assets.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/log.hpp" #include "utils/log.hpp"
#include "utils/mem_utils.hpp"
#include "utils/string_utils.hpp" #include "utils/string_utils.hpp"
#ifdef ANDROID #ifdef ANDROID
@ -1560,23 +1561,16 @@ bool FileManager::removeDirectory(const std::string &name) const
bool FileManager::copyFile(const std::string &source, const std::string &dest) bool FileManager::copyFile(const std::string &source, const std::string &dest)
{ {
FILE *f_source = FileUtils::fopenU8Path(source, "rb"); FILE *f_source = FileUtils::fopenU8Path(source, "rb");
if(!f_source) return false;
FILE *f_dest = FileUtils::fopenU8Path(dest, "wb"); FILE *f_dest = FileUtils::fopenU8Path(dest, "wb");
if(!f_dest) constexpr int BUFFER_SIZE=32768;
{
fclose(f_source);
return false;
}
const int BUFFER_SIZE=32768;
char *buffer = new char[BUFFER_SIZE]; char *buffer = new char[BUFFER_SIZE];
if(!buffer) auto scoped = [&]() {
{ if (f_source) fclose(f_source);
fclose(f_source); if (f_dest) fclose(f_dest);
fclose(f_dest); if (buffer) delete [] buffer;
return false; };
} MemUtils::deref<decltype(scoped)> cls(scoped);
if(!f_source || !f_dest || !buffer) return false;
size_t n; size_t n;
while((n=fread(buffer, 1, BUFFER_SIZE, f_source))>0) while((n=fread(buffer, 1, BUFFER_SIZE, f_source))>0)
{ {
@ -1584,17 +1578,11 @@ bool FileManager::copyFile(const std::string &source, const std::string &dest)
{ {
Log::error("FileManager", "Write error copying '%s' to '%s", Log::error("FileManager", "Write error copying '%s' to '%s",
source.c_str(), dest.c_str()); source.c_str(), dest.c_str());
delete[] buffer;
fclose(f_source);
fclose(f_dest);
return false; return false;
} // if fwrite()!=n } // if fwrite()!=n
} // while } // while
delete[] buffer;
fclose(f_source);
fclose(f_dest);
return true; return true;
} // copyFile } // copyFile

View File

@ -27,6 +27,7 @@
#include "tracks/track.hpp" #include "tracks/track.hpp"
#include "tracks/track_manager.hpp" #include "tracks/track_manager.hpp"
#include "utils/file_utils.hpp" #include "utils/file_utils.hpp"
#include "utils/mem_utils.hpp"
#include "utils/string_utils.hpp" #include "utils/string_utils.hpp"
#include <irrlicht.h> #include <irrlicht.h>
@ -112,6 +113,8 @@ bool ReplayPlay::addReplayFile(const std::string& fn, bool custom_replay, int ca
FILE* fd = FileUtils::fopenU8Path(custom_replay ? fn : FILE* fd = FileUtils::fopenU8Path(custom_replay ? fn :
file_manager->getReplayDir() + fn, "r"); file_manager->getReplayDir() + fn, "r");
if (fd == NULL) return false; if (fd == NULL) return false;
auto scoped = [&]() { fclose(fd); };
MemUtils::deref<decltype(scoped)> cls(scoped);
ReplayData rd; ReplayData rd;
// custom_replay is true when full path of filename is given // custom_replay is true when full path of filename is given
@ -124,7 +127,6 @@ bool ReplayPlay::addReplayFile(const std::string& fn, bool custom_replay, int ca
{ {
Log::warn("Replay", "No Version information " Log::warn("Replay", "No Version information "
"found in replay file (bogus replay file)."); "found in replay file (bogus replay file).");
fclose(fd);
return false; return false;
} }
if (version > getCurrentReplayVersion() || if (version > getCurrentReplayVersion() ||
@ -134,7 +136,6 @@ bool ReplayPlay::addReplayFile(const std::string& fn, bool custom_replay, int ca
Log::warn("Replay", "STK replay version is '%d'", getCurrentReplayVersion()); Log::warn("Replay", "STK replay version is '%d'", getCurrentReplayVersion());
Log::warn("Replay", "Minimum supported replay version is '%d'", getMinSupportedReplayVersion()); Log::warn("Replay", "Minimum supported replay version is '%d'", getMinSupportedReplayVersion());
Log::warn("Replay", "Skipped '%s'", fn.c_str()); Log::warn("Replay", "Skipped '%s'", fn.c_str());
fclose(fd);
return false; return false;
} }
rd.m_replay_version = version; rd.m_replay_version = version;
@ -145,7 +146,6 @@ bool ReplayPlay::addReplayFile(const std::string& fn, bool custom_replay, int ca
if(sscanf(s, "stk_version: %1023s", s1) != 1) if(sscanf(s, "stk_version: %1023s", s1) != 1)
{ {
Log::warn("Replay", "No STK release version found in replay file, '%s'.", fn.c_str()); Log::warn("Replay", "No STK release version found in replay file, '%s'.", fn.c_str());
fclose(fd);
return false; return false;
} }
rd.m_stk_version = s1; rd.m_stk_version = s1;
@ -194,7 +194,6 @@ bool ReplayPlay::addReplayFile(const std::string& fn, bool custom_replay, int ca
if(sscanf(s, "kart_color: %f", &f) != 1) if(sscanf(s, "kart_color: %f", &f) != 1)
{ {
Log::warn("Replay", "Kart color missing in replay file, '%s'.", fn.c_str()); Log::warn("Replay", "Kart color missing in replay file, '%s'.", fn.c_str());
fclose(fd);
return false; return false;
} }
rd.m_kart_color.push_back(f); rd.m_kart_color.push_back(f);
@ -208,7 +207,6 @@ bool ReplayPlay::addReplayFile(const std::string& fn, bool custom_replay, int ca
if(sscanf(s, "reverse: %d", &reverse) != 1) if(sscanf(s, "reverse: %d", &reverse) != 1)
{ {
Log::warn("Replay", "No reverse info found in replay file, '%s'.", fn.c_str()); Log::warn("Replay", "No reverse info found in replay file, '%s'.", fn.c_str());
fclose(fd);
return false; return false;
} }
rd.m_reverse = reverse != 0; rd.m_reverse = reverse != 0;
@ -217,7 +215,6 @@ bool ReplayPlay::addReplayFile(const std::string& fn, bool custom_replay, int ca
if (sscanf(s, "difficulty: %u", &rd.m_difficulty) != 1) if (sscanf(s, "difficulty: %u", &rd.m_difficulty) != 1)
{ {
Log::warn("Replay", " No difficulty found in replay file, '%s'.", fn.c_str()); Log::warn("Replay", " No difficulty found in replay file, '%s'.", fn.c_str());
fclose(fd);
return false; return false;
} }
@ -227,7 +224,6 @@ bool ReplayPlay::addReplayFile(const std::string& fn, bool custom_replay, int ca
if (sscanf(s, "mode: %1023s", s1) != 1) if (sscanf(s, "mode: %1023s", s1) != 1)
{ {
Log::warn("Replay", "Replay mode not found in replay file, '%s'.", fn.c_str()); Log::warn("Replay", "Replay mode not found in replay file, '%s'.", fn.c_str());
fclose(fd);
return false; return false;
} }
rd.m_minor_mode = s1; rd.m_minor_mode = s1;
@ -241,7 +237,6 @@ bool ReplayPlay::addReplayFile(const std::string& fn, bool custom_replay, int ca
if (sscanf(s, "track: %1023s", s1) != 1) if (sscanf(s, "track: %1023s", s1) != 1)
{ {
Log::warn("Replay", "Track info not found in replay file, '%s'.", fn.c_str()); Log::warn("Replay", "Track info not found in replay file, '%s'.", fn.c_str());
fclose(fd);
return false; return false;
} }
rd.m_track_name = std::string(s1); rd.m_track_name = std::string(s1);
@ -257,7 +252,6 @@ bool ReplayPlay::addReplayFile(const std::string& fn, bool custom_replay, int ca
{ {
Log::warn("Replay", "Track '%s' used in replay '%s' not found in STK!", Log::warn("Replay", "Track '%s' used in replay '%s' not found in STK!",
rd.m_track_name.c_str(), fn.c_str()); rd.m_track_name.c_str(), fn.c_str());
fclose(fd);
return false; return false;
} }
@ -267,7 +261,6 @@ bool ReplayPlay::addReplayFile(const std::string& fn, bool custom_replay, int ca
if (sscanf(s, "laps: %u", &rd.m_laps) != 1) if (sscanf(s, "laps: %u", &rd.m_laps) != 1)
{ {
Log::warn("Replay", "No number of laps found in replay file, '%s'.", fn.c_str()); Log::warn("Replay", "No number of laps found in replay file, '%s'.", fn.c_str());
fclose(fd);
return false; return false;
} }
@ -275,7 +268,6 @@ bool ReplayPlay::addReplayFile(const std::string& fn, bool custom_replay, int ca
if (sscanf(s, "min_time: %f", &rd.m_min_time) != 1) if (sscanf(s, "min_time: %f", &rd.m_min_time) != 1)
{ {
Log::warn("Replay", "Finish time not found in replay file, '%s'.", fn.c_str()); Log::warn("Replay", "Finish time not found in replay file, '%s'.", fn.c_str());
fclose(fd);
return false; return false;
} }
@ -285,7 +277,6 @@ bool ReplayPlay::addReplayFile(const std::string& fn, bool custom_replay, int ca
if (sscanf(s, "replay_uid: %" PRIu64, &rd.m_replay_uid) != 1) if (sscanf(s, "replay_uid: %" PRIu64, &rd.m_replay_uid) != 1)
{ {
Log::warn("Replay", "Replay UID not found in replay file, '%s'.", fn.c_str()); Log::warn("Replay", "Replay UID not found in replay file, '%s'.", fn.c_str());
fclose(fd);
return false; return false;
} }
} }
@ -293,7 +284,6 @@ bool ReplayPlay::addReplayFile(const std::string& fn, bool custom_replay, int ca
else else
rd.m_replay_uid = call_index; rd.m_replay_uid = call_index;
fclose(fd);
m_replay_file_list.push_back(rd); m_replay_file_list.push_back(rd);
assert(m_replay_file_list.size() > 0); assert(m_replay_file_list.size() > 0);

44
src/utils/mem_utils.hpp Normal file
View File

@ -0,0 +1,44 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2022 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_MEM_UTILS_HPP
#define HEADER_MEM_UTILS_HPP
namespace MemUtils {
template<typename callback>
class deref {
callback cb;
bool chg;
public:
deref(callback _c) : cb(std::move(_c)) {}
deref(const deref &) = delete;
deref& operator=(const deref &) = delete;
deref(deref &&other) :
cb(other.cb),
chg(other.chg)
{
other.chg = false;
}
~deref()
{
if (chg)
cb();
}
};
}
#endif