tagparser/basicfileinfo.cpp

266 lines
7.1 KiB
C++
Raw Normal View History

2015-09-06 19:57:33 +02:00
#include "./basicfileinfo.h"
2015-04-22 19:22:01 +02:00
2018-03-11 19:15:13 +01:00
#include <c++utilities/conversion/stringconversion.h>
2015-04-22 19:22:01 +02:00
using namespace std;
2019-06-10 22:49:11 +02:00
using namespace CppUtilities;
2015-04-22 19:22:01 +02:00
/*!
* \brief Contains all classes and functions of the TagInfo library.
*/
namespace TagParser {
2015-04-22 19:22:01 +02:00
/*!
* \class BasicFileInfo
2015-04-22 19:22:01 +02:00
* \brief The BasicFileInfo class provides basic file information such as
* file name, extension, directory and size for a specified file.
*/
/*!
* \brief Constructs a new BasicFileInfo for the specified file.
*
* \param path Specifies the absolute or relative path of the file.
*/
BasicFileInfo::BasicFileInfo()
: m_size(0)
, m_readOnly(false)
{
m_file.exceptions(ios_base::failbit | ios_base::badbit);
}
/*!
* \brief Constructs a new BasicFileInfo for the specified file.
*
* \param path Specifies the absolute or relative path of the file.
*/
BasicFileInfo::BasicFileInfo(std::string &&path)
: m_path(std::move(path))
, m_size(0)
, m_readOnly(false)
{
m_file.exceptions(ios_base::failbit | ios_base::badbit);
}
2015-04-22 19:22:01 +02:00
/*!
* \brief Constructs a new BasicFileInfo for the specified file.
*
* \param path Specifies the absolute or relative path of the file.
*/
BasicFileInfo::BasicFileInfo(std::string_view path)
2018-03-07 01:17:50 +01:00
: m_path(path)
, m_size(0)
, m_readOnly(false)
2015-04-22 19:22:01 +02:00
{
m_file.exceptions(ios_base::failbit | ios_base::badbit);
2015-04-22 19:22:01 +02:00
}
/*!
* \brief Destroys the BasicFileInfo.
*
* A possibly opened std::fstream will be closed.
*/
BasicFileInfo::~BasicFileInfo()
{
close();
}
/*!
* \brief Opens a std::fstream for the current file. Does nothing a stream is already open.
2016-03-12 18:36:10 +01:00
* \param readOnly Indicates whether the stream should be opend as read-only.
2015-04-22 19:22:01 +02:00
* \throws Throws std::ios_base::failure when an IO error occurs.
*/
2016-03-12 18:36:10 +01:00
void BasicFileInfo::open(bool readOnly)
2015-04-22 19:22:01 +02:00
{
2018-03-07 01:17:50 +01:00
if (!isOpen()) {
2016-03-12 18:36:10 +01:00
reopen(readOnly);
2015-04-22 19:22:01 +02:00
}
}
/*!
* \brief Opens a std::fstream for the current file. Closes a possibly already opened stream and
* clears all flags before.
2016-03-12 18:36:10 +01:00
* \param readOnly Indicates whether the stream should be opend as read-only.
2015-04-22 19:22:01 +02:00
* \throws Throws std::ios_base::failure when an IO error occurs.
*/
2016-03-12 18:36:10 +01:00
void BasicFileInfo::reopen(bool readOnly)
2015-04-22 19:22:01 +02:00
{
invalidated();
m_file.open(
pathForOpen(path()).data(), (m_readOnly = readOnly) ? ios_base::in | ios_base::binary : ios_base::in | ios_base::out | ios_base::binary);
2015-04-22 19:22:01 +02:00
m_file.seekg(0, ios_base::end);
2019-03-13 19:06:42 +01:00
m_size = static_cast<std::uint64_t>(m_file.tellg());
2015-04-22 19:22:01 +02:00
m_file.seekg(0, ios_base::beg);
}
/*!
* \brief A possibly opened std::fstream will be closed. All flags of the stream will be cleared.
*/
void BasicFileInfo::close()
{
2018-03-07 01:17:50 +01:00
if (isOpen()) {
2015-04-22 19:22:01 +02:00
m_file.close();
}
m_file.clear();
}
/*!
* \brief Invalidates the file info manually.
*/
void BasicFileInfo::invalidate()
{
invalidated();
}
2015-04-22 19:22:01 +02:00
/*!
* \brief Sets the current file.
*
* A possibly opened std::fstream will be closed and invalidated() will be called.
*
* \param path Specifies the absolute or relative path of the file to be set.
*/
void BasicFileInfo::setPath(std::string_view path)
2015-04-22 19:22:01 +02:00
{
2018-03-07 01:17:50 +01:00
if (path != m_path) {
2015-04-22 19:22:01 +02:00
invalidated();
m_path = path;
}
}
/*!
* \brief Sets the current file.
*
* A possibly opened std::fstream will be closed and invalidated() will be called.
*
* \param path Specifies the absolute or relative path of the file to be set.
*/
void BasicFileInfo::setPath(std::string &&path)
{
if (path != m_path) {
invalidated();
m_path = path;
}
}
2015-04-22 19:22:01 +02:00
/*!
* \brief Returns the file name of the given file.
*
* \param path Specifies the path of the file.
2021-07-02 03:00:50 +02:00
* \param cutExtension Indicates whether the extension/suffix should be cut.
2015-04-22 19:22:01 +02:00
*/
std::string BasicFileInfo::fileName(std::string_view path, bool cutExtension)
2015-04-22 19:22:01 +02:00
{
const auto lastSlash = path.rfind('/');
const auto lastBackSlash = path.rfind('\\');
const auto lastPoint = cutExtension ? path.rfind('.') : string::npos;
auto lastSeparator = decltype(lastSlash)();
2018-03-07 01:17:50 +01:00
if (lastSlash == string::npos && lastBackSlash == string::npos) {
return std::string(lastPoint == string::npos ? path : path.substr(0, lastPoint));
2018-03-07 01:17:50 +01:00
} else if (lastSlash == string::npos) {
2015-04-22 19:22:01 +02:00
lastSeparator = lastBackSlash;
2018-03-07 01:17:50 +01:00
} else if (lastBackSlash == string::npos) {
2015-04-22 19:22:01 +02:00
lastSeparator = lastSlash;
} else {
lastSeparator = lastSlash > lastBackSlash ? lastSlash : lastBackSlash;
}
return std::string(lastPoint != string::npos ? path.substr(lastSeparator + 1, lastPoint - lastSeparator - 1) : path.substr(lastSeparator + 1));
2015-04-22 19:22:01 +02:00
}
/*!
* \brief Returns the file name of the current file.
*
2021-07-02 03:00:50 +02:00
* \param cutExtension Indicates whether the extension should be cut.
2015-04-22 19:22:01 +02:00
*/
std::string BasicFileInfo::fileName(bool cutExtension) const
2015-04-22 19:22:01 +02:00
{
return fileName(m_path, cutExtension);
}
/*!
* \brief Returns the extension of the given file.
*
* \param path Specifies the path of the file.
*/
std::string BasicFileInfo::extension(std::string_view path)
2015-04-22 19:22:01 +02:00
{
const auto lastPoint = path.rfind('.');
if (lastPoint == std::string::npos) {
return std::string();
2015-04-22 19:22:01 +02:00
} else {
return std::string(path.data() + lastPoint, path.size() - lastPoint);
2015-04-22 19:22:01 +02:00
}
}
/*!
* \brief Returns the extension of the current file.
*/
std::string BasicFileInfo::extension() const
2015-04-22 19:22:01 +02:00
{
return extension(m_path);
}
/*!
* \brief Returns a copy of the given path without the extension/suffix.
*/
std::string BasicFileInfo::pathWithoutExtension(std::string_view fullPath)
2015-04-22 19:22:01 +02:00
{
const auto lastPoint = fullPath.rfind('.');
return std::string(lastPoint != std::string::npos ? fullPath.substr(0, lastPoint) : fullPath);
2015-04-22 19:22:01 +02:00
}
/*!
* \brief Returns the path of the current file without the extension/suffix.
*/
std::string BasicFileInfo::pathWithoutExtension() const
2015-04-22 19:22:01 +02:00
{
return pathWithoutExtension(m_path);
}
/*!
* \brief Returns the path of the directory containing the given file.
*/
std::string BasicFileInfo::containingDirectory(std::string_view path)
2015-04-22 19:22:01 +02:00
{
const auto lastSlash = path.rfind('/');
const auto lastBackSlash = path.rfind('\\');
auto lastSeparator = decltype(lastSlash)();
if (lastSlash == string::npos && lastBackSlash == std::string::npos) {
return std::string();
2018-03-07 01:17:50 +01:00
} else if (lastSlash == string::npos) {
2015-04-22 19:22:01 +02:00
lastSeparator = lastBackSlash;
2018-03-07 01:17:50 +01:00
} else if (lastBackSlash == string::npos) {
2015-04-22 19:22:01 +02:00
lastSeparator = lastSlash;
} else {
lastSeparator = lastSlash > lastBackSlash ? lastSlash : lastBackSlash;
}
2018-03-07 01:17:50 +01:00
if (lastSeparator > 0) {
return std::string(path.substr(0, lastSeparator));
2015-04-22 19:22:01 +02:00
} else {
return std::string();
2015-04-22 19:22:01 +02:00
}
}
/*!
* \brief Returns the path of the directory containing the current file.
*
* The returned path is relative if the path of the file (specified using
* the setPath() method) is relative.
*/
string BasicFileInfo::containingDirectory() const
{
return containingDirectory(m_path);
}
/*!
* \brief This function is called when the BasicFileInfo gets invalidated.
* This is the case when the current file changes or is reopened.
2015-04-22 19:22:01 +02:00
*
* When subclassing and overwriting this virtual method invoke the base
* implementation by calling BasicFileInfo::invalidated() before the reimplemented code.
*/
void BasicFileInfo::invalidated()
{
m_size = 0;
close();
}
2018-03-07 01:17:50 +01:00
} // namespace TagParser