diff --git a/basicfileinfo.cpp b/basicfileinfo.cpp index 65315c5..a2fd67c 100644 --- a/basicfileinfo.cpp +++ b/basicfileinfo.cpp @@ -15,6 +15,31 @@ namespace TagParser { * 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); +} + /*! * \brief Constructs a new BasicFileInfo for the specified file. * @@ -100,20 +125,35 @@ void BasicFileInfo::setPath(std::string_view 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; + } +} + /*! * \brief Returns the file name of the given file. * * \param path Specifies the path of the file. * \param cutExtension Indicates whether the extension/suffix should be cutted. */ -string BasicFileInfo::fileName(const string &path, bool cutExtension) +std::string BasicFileInfo::fileName(std::string_view path, bool cutExtension) { - size_t lastSlash = path.rfind('/'); - size_t lastBackSlash = path.rfind('\\'); - size_t lastPoint = cutExtension ? path.rfind('.') : string::npos; - size_t lastSeparator; + const auto lastSlash = path.rfind('/'); + const auto lastBackSlash = path.rfind('\\'); + const auto lastPoint = cutExtension ? path.rfind('.') : string::npos; + auto lastSeparator = decltype(lastSlash)(); if (lastSlash == string::npos && lastBackSlash == string::npos) { - return (lastPoint == string::npos) ? path : path.substr(0, lastPoint); + return std::string(lastPoint == string::npos ? path : path.substr(0, lastPoint)); } else if (lastSlash == string::npos) { lastSeparator = lastBackSlash; } else if (lastBackSlash == string::npos) { @@ -121,7 +161,7 @@ string BasicFileInfo::fileName(const string &path, bool cutExtension) } else { lastSeparator = lastSlash > lastBackSlash ? lastSlash : lastBackSlash; } - return (lastPoint != string::npos) ? path.substr(lastSeparator + 1, lastPoint - lastSeparator - 1) : path.substr(lastSeparator + 1); + return std::string(lastPoint != string::npos ? path.substr(lastSeparator + 1, lastPoint - lastSeparator - 1) : path.substr(lastSeparator + 1)); } /*! @@ -129,7 +169,7 @@ string BasicFileInfo::fileName(const string &path, bool cutExtension) * * \param cutExtension Indicates whether the extension should be cutted. */ -string BasicFileInfo::fileName(bool cutExtension) const +std::string BasicFileInfo::fileName(bool cutExtension) const { return fileName(m_path, cutExtension); } @@ -141,7 +181,7 @@ string BasicFileInfo::fileName(bool cutExtension) const */ std::string BasicFileInfo::extension(std::string_view path) { - std::size_t lastPoint = path.rfind('.'); + const auto lastPoint = path.rfind('.'); if (lastPoint == std::string::npos) { return std::string(); } else { @@ -152,7 +192,7 @@ std::string BasicFileInfo::extension(std::string_view path) /*! * \brief Returns the extension of the current file. */ -string BasicFileInfo::extension() const +std::string BasicFileInfo::extension() const { return extension(m_path); } @@ -160,16 +200,16 @@ string BasicFileInfo::extension() const /*! * \brief Returns a copy of the given path without the extension/suffix. */ -string BasicFileInfo::pathWithoutExtension(const string &fullPath) +std::string BasicFileInfo::pathWithoutExtension(std::string_view fullPath) { - size_t lastPoint = fullPath.rfind('.'); - return lastPoint != string::npos ? fullPath.substr(0, lastPoint) : fullPath; + const auto lastPoint = fullPath.rfind('.'); + return std::string(lastPoint != std::string::npos ? fullPath.substr(0, lastPoint) : fullPath); } /*! * \brief Returns the path of the current file without the extension/suffix. */ -string BasicFileInfo::pathWithoutExtension() const +std::string BasicFileInfo::pathWithoutExtension() const { return pathWithoutExtension(m_path); } @@ -177,13 +217,13 @@ string BasicFileInfo::pathWithoutExtension() const /*! * \brief Returns the path of the directory containing the given file. */ -string BasicFileInfo::containingDirectory(const string &path) +std::string BasicFileInfo::containingDirectory(std::string_view path) { - size_t lastSlash = path.rfind('/'); - size_t lastBackSlash = path.rfind('\\'); - size_t lastSeparator; - if (lastSlash == string::npos && lastBackSlash == string::npos) { - return string(); + 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(); } else if (lastSlash == string::npos) { lastSeparator = lastBackSlash; } else if (lastBackSlash == string::npos) { @@ -192,9 +232,9 @@ string BasicFileInfo::containingDirectory(const string &path) lastSeparator = lastSlash > lastBackSlash ? lastSlash : lastBackSlash; } if (lastSeparator > 0) { - return path.substr(0, lastSeparator); + return std::string(path.substr(0, lastSeparator)); } else { - return string(); + return std::string(); } } diff --git a/basicfileinfo.h b/basicfileinfo.h index 2d25eea..7fbb59c 100644 --- a/basicfileinfo.h +++ b/basicfileinfo.h @@ -14,7 +14,9 @@ namespace TagParser { class TAG_PARSER_EXPORT BasicFileInfo { public: // constructor, destructor - explicit BasicFileInfo(std::string_view path = std::string_view()); + explicit BasicFileInfo(); + explicit BasicFileInfo(std::string &&path); + explicit BasicFileInfo(std::string_view path); BasicFileInfo(const BasicFileInfo &) = delete; BasicFileInfo &operator=(const BasicFileInfo &) = delete; virtual ~BasicFileInfo(); @@ -32,20 +34,22 @@ public: // methods to get, set path (components) const std::string &path() const; void setPath(std::string_view path); - static std::string fileName(const std::string &path, bool cutExtension = false); + void setPath(std::string &&path); + static std::string fileName(std::string_view path, bool cutExtension = false); std::string fileName(bool cutExtension = false) const; static std::string extension(std::string_view path); std::string extension() const; - static std::string pathWithoutExtension(const std::string &fullPath); + static std::string pathWithoutExtension(std::string_view fullPath); std::string pathWithoutExtension() const; - static std::string containingDirectory(const std::string &path); + static std::string containingDirectory(std::string_view path); std::string containingDirectory() const; - static std::string_view pathForOpen(const std::string &url); + static std::string_view pathForOpen(std::string_view url); // methods to get, set the file size std::uint64_t size() const; void reportSizeChanged(std::uint64_t newSize); - void reportPathChanged(const std::string &newPath); + void reportPathChanged(std::string_view newPath); + void reportPathChanged(std::string &&newPath); protected: virtual void invalidated(); @@ -126,18 +130,27 @@ inline void BasicFileInfo::reportSizeChanged(std::uint64_t newSize) * \brief Call this function to report that the path changed. * \remarks Should be called after associating another file to the stream() manually. */ -inline void BasicFileInfo::reportPathChanged(const std::string &newPath) +inline void BasicFileInfo::reportPathChanged(std::string_view newPath) { m_path = newPath; } +/*! + * \brief Call this function to report that the path changed. + * \remarks Should be called after associating another file to the stream() manually. + */ +inline void BasicFileInfo::reportPathChanged(std::string &&newPath) +{ + m_path = std::move(newPath); +} + /*! * \brief Returns removes the "file:/" prefix from \a url to be able to pass it to functions * like open(), stat() and truncate(). * \remarks If \a url is already a plain path it won't changed. * \returns Returns a pointer the URL data itself. No copy is made. */ -inline std::string_view BasicFileInfo::pathForOpen(const std::string &url) +inline std::string_view BasicFileInfo::pathForOpen(std::string_view url) { return CppUtilities::startsWith(url, "file:/") ? url.data() + 6 : url.data(); } diff --git a/mediafileinfo.cpp b/mediafileinfo.cpp index 2b3ffde..afd040e 100644 --- a/mediafileinfo.cpp +++ b/mediafileinfo.cpp @@ -76,10 +76,13 @@ namespace TagParser { */ /*! - * \brief Constructs a new MediaFileInfo. + * \brief Constructs a new MediaFileInfo for the specified file. + * + * \param path Specifies the absolute or relative path of the file. */ -MediaFileInfo::MediaFileInfo() - : m_containerParsingStatus(ParsingStatus::NotParsedYet) +MediaFileInfo::MediaFileInfo(std::string &&path) + : BasicFileInfo(std::move(path)) + , m_containerParsingStatus(ParsingStatus::NotParsedYet) , m_containerFormat(ContainerFormat::Unknown) , m_containerOffset(0) , m_actualExistingId3v1Tag(false) @@ -100,29 +103,18 @@ MediaFileInfo::MediaFileInfo() } /*! - * \brief Constructs a new MediaFileInfo for the specified file. - * - * \param path Specifies the absolute or relative path of the file. + * \brief Constructs a new MediaFileInfo. */ -MediaFileInfo::MediaFileInfo(const string &path) - : BasicFileInfo(path) - , m_containerParsingStatus(ParsingStatus::NotParsedYet) - , m_containerFormat(ContainerFormat::Unknown) - , m_containerOffset(0) - , m_actualExistingId3v1Tag(false) - , m_tracksParsingStatus(ParsingStatus::NotParsedYet) - , m_tagsParsingStatus(ParsingStatus::NotParsedYet) - , m_chaptersParsingStatus(ParsingStatus::NotParsedYet) - , m_attachmentsParsingStatus(ParsingStatus::NotParsedYet) - , m_minPadding(0) - , m_maxPadding(0) - , m_preferredPadding(0) - , m_tagPosition(ElementPosition::BeforeData) - , m_indexPosition(ElementPosition::BeforeData) - , m_forceFullParse(MEDIAINFO_CPP_FORCE_FULL_PARSE) - , m_forceRewrite(true) - , m_forceTagPosition(true) - , m_forceIndexPosition(true) +MediaFileInfo::MediaFileInfo() + : MediaFileInfo(std::string()) +{ +} + +/*! + * \brief Constructs a new MediaFileInfo. + */ +MediaFileInfo::MediaFileInfo(std::string_view path) + : MediaFileInfo(std::string(path)) { } diff --git a/mediafileinfo.h b/mediafileinfo.h index f1a4410..79da0bb 100644 --- a/mediafileinfo.h +++ b/mediafileinfo.h @@ -46,7 +46,8 @@ class TAG_PARSER_EXPORT MediaFileInfo : public BasicFileInfo { public: // constructor, destructor explicit MediaFileInfo(); - explicit MediaFileInfo(const std::string &path); + explicit MediaFileInfo(std::string_view path); + explicit MediaFileInfo(std::string &&path); MediaFileInfo(const MediaFileInfo &) = delete; MediaFileInfo &operator=(const MediaFileInfo &) = delete; ~MediaFileInfo() override; @@ -123,9 +124,11 @@ public: // methods to get, set object behaviour const std::string &backupDirectory() const; - void setBackupDirectory(const std::string &backupDirectory); + void setBackupDirectory(std::string_view backupDirectory); + void setBackupDirectory(std::string &&backupDirectory); const std::string &saveFilePath() const; - void setSaveFilePath(const std::string &saveFilePath); + void setSaveFilePath(std::string_view saveFilePath); + void setSaveFilePath(std::string &&saveFilePath); const std::string &writingApplication() const; void setWritingApplication(std::string_view writingApplication); bool isForcingFullParse() const; @@ -357,11 +360,20 @@ inline const std::string &MediaFileInfo::backupDirectory() const * \brief Sets the directory used to store backup files. * \remarks If empty, backup files will be stored in the same directory of the file being modified. */ -inline void MediaFileInfo::setBackupDirectory(const std::string &backupDirectory) +inline void MediaFileInfo::setBackupDirectory(std::string_view backupDirectory) { m_backupDirectory = backupDirectory; } +/*! + * \brief Sets the directory used to store backup files. + * \remarks If empty, backup files will be stored in the same directory of the file being modified. + */ +inline void MediaFileInfo::setBackupDirectory(std::string &&backupDirectory) +{ + m_backupDirectory = std::move(backupDirectory); +} + /*! * \brief Returns the "save file path" which has been set using setSaveFilePath(). * \sa setSaveFilePath() @@ -385,11 +397,19 @@ inline const std::string &MediaFileInfo::saveFilePath() const * * \remarks \a saveFilePath mustn't be the current path(). */ -inline void MediaFileInfo::setSaveFilePath(const std::string &saveFilePath) +inline void MediaFileInfo::setSaveFilePath(std::string_view saveFilePath) { m_saveFilePath = saveFilePath; } +/*! + * \brief Sets the "save file path". + */ +inline void MediaFileInfo::setSaveFilePath(std::string &&saveFilePath) +{ + m_saveFilePath = std::move(saveFilePath); +} + /*! * \brief Sets the writing application as container-level meta-data. * \remarks This is not read from the file when parsing and only used when saving changes. diff --git a/tests/mediafileinfo.cpp b/tests/mediafileinfo.cpp index 4625475..eb69253 100644 --- a/tests/mediafileinfo.cpp +++ b/tests/mediafileinfo.cpp @@ -70,7 +70,7 @@ void MediaFileInfoTests::testInitialStatus() void MediaFileInfoTests::testFileSystemMethods() { - MediaFileInfo file("/usr/bin/unsupported.bin"); + MediaFileInfo file("/usr/bin/unsupported.bin"sv); CPPUNIT_ASSERT_EQUAL("/usr/bin"s, file.containingDirectory()); CPPUNIT_ASSERT_EQUAL("unsupported.bin"s, file.fileName()); CPPUNIT_ASSERT_EQUAL("unsupported"s, file.fileName(true));