From 64d98f5530cae7168ae769c1865bb600fea7fe0f Mon Sep 17 00:00:00 2001 From: Martchus Date: Sat, 30 Jan 2021 21:53:06 +0100 Subject: [PATCH] Use std::string_view where it makes sense --- abstractattachment.cpp | 8 +- abstractattachment.h | 20 +-- abstractcontainer.h | 4 +- abstracttrack.cpp | 25 ++-- abstracttrack.h | 40 +++--- backuphelper.cpp | 16 +-- basicfileinfo.cpp | 17 +-- basicfileinfo.h | 10 +- caseinsensitivecomparer.h | 4 + diagnostics.cpp | 4 +- diagnostics.h | 6 +- fieldbasedtag.h | 4 +- flac/flacmetadata.cpp | 14 +- flac/flacmetadata.h | 4 +- id3/id3genres.cpp | 8 +- id3/id3genres.h | 12 +- id3/id3v1tag.cpp | 2 +- id3/id3v1tag.h | 4 +- id3/id3v2frame.h | 10 +- id3/id3v2tag.h | 2 +- matroska/ebmlelement.cpp | 21 +-- matroska/ebmlelement.h | 7 +- matroska/matroskacontainer.cpp | 17 ++- matroska/matroskaid.cpp | 4 +- matroska/matroskaid.h | 3 +- matroska/matroskatag.cpp | 50 ++++---- matroska/matroskatag.h | 2 +- matroska/matroskatagfield.h | 6 +- matroska/matroskatagid.h | 226 +++++++++++++++++---------------- matroska/matroskatrack.cpp | 4 +- matroska/matroskatrack.h | 2 +- mediafileinfo.cpp | 16 +-- mediafileinfo.h | 30 ++--- mediaformat.cpp | 10 +- mediaformat.h | 11 +- mp4/mp4container.cpp | 12 +- mp4/mp4ids.cpp | 10 +- mp4/mp4ids.h | 11 +- mp4/mp4tag.cpp | 9 +- mp4/mp4tag.h | 36 ++---- mp4/mp4tagfield.cpp | 2 +- mp4/mp4tagfield.h | 8 +- mpegaudio/mpegaudioframe.cpp | 2 +- mpegaudio/mpegaudioframe.h | 3 +- ogg/oggcontainer.cpp | 9 +- ogg/oggcontainer.h | 4 +- signature.cpp | 28 ++-- signature.h | 17 ++- size.cpp | 2 +- size.h | 3 +- tag.h | 10 +- tagtarget.cpp | 12 +- tagtarget.h | 2 +- tagvalue.cpp | 6 +- tagvalue.h | 51 +++++++- tests/overallgeneral.cpp | 10 +- vorbis/vorbiscomment.cpp | 50 ++++---- vorbis/vorbiscomment.h | 2 +- vorbis/vorbiscommentfield.h | 6 +- vorbis/vorbiscommentids.h | 82 ++++++------ 60 files changed, 512 insertions(+), 498 deletions(-) diff --git a/abstractattachment.cpp b/abstractattachment.cpp index e8dba93..1f018b2 100644 --- a/abstractattachment.cpp +++ b/abstractattachment.cpp @@ -100,7 +100,7 @@ void StreamDataBlock::copyTo(ostream &stream) const * * \throws Throws ios_base::failure when an IO error occurs. */ -FileDataBlock::FileDataBlock(const string &path, Diagnostics &diag) +FileDataBlock::FileDataBlock(std::string_view path, Diagnostics &diag) : m_fileInfo(make_unique()) { m_fileInfo->setPath(path); @@ -167,7 +167,7 @@ void AbstractAttachment::clear() * * When such an exception is thrown, the attachment remains unchanged. */ -void AbstractAttachment::setFile(const std::string &path, Diagnostics &diag) +void AbstractAttachment::setFile(string_view path, Diagnostics &diag) { m_data.reset(); auto file = make_unique(path, diag); @@ -175,8 +175,8 @@ void AbstractAttachment::setFile(const std::string &path, Diagnostics &diag) if (!fileName.empty()) { m_name = fileName; } - const char *mimeType = file->fileInfo()->mimeType(); - if (*mimeType) { + const auto mimeType = file->fileInfo()->mimeType(); + if (!mimeType.empty()) { m_mimeType = mimeType; } m_data = move(file); diff --git a/abstractattachment.h b/abstractattachment.h index 5a48cb9..9c968fb 100644 --- a/abstractattachment.h +++ b/abstractattachment.h @@ -89,7 +89,7 @@ inline void StreamDataBlock::discardBuffer() class TAG_PARSER_EXPORT FileDataBlock : public StreamDataBlock { public: - FileDataBlock(const std::string &path, Diagnostics &diag); + FileDataBlock(std::string_view path, Diagnostics &diag); ~FileDataBlock(); const MediaFileInfo *fileInfo() const; @@ -105,16 +105,16 @@ inline const MediaFileInfo *FileDataBlock::fileInfo() const class TAG_PARSER_EXPORT AbstractAttachment { public: const std::string &description() const; - void setDescription(const std::string &description); + void setDescription(std::string_view description); const std::string &name() const; - void setName(const std::string &name); + void setName(std::string_view name); const std::string &mimeType() const; - void setMimeType(const std::string &mimeType); + void setMimeType(std::string_view mimeType); std::uint64_t id() const; - void setId(const std::uint64_t &id); + void setId(std::uint64_t id); const StreamDataBlock *data() const; void setData(std::unique_ptr &&data); - void setFile(const std::string &path, Diagnostics &diag); + void setFile(std::string_view path, Diagnostics &diag); bool isDataFromFile() const; std::string label() const; void clear(); @@ -156,7 +156,7 @@ inline const std::string &AbstractAttachment::description() const /*! * \brief Sets a description of the attachment. */ -inline void AbstractAttachment::setDescription(const std::string &description) +inline void AbstractAttachment::setDescription(std::string_view description) { m_description = description; } @@ -172,7 +172,7 @@ inline const std::string &AbstractAttachment::name() const /*! * \brief Sets the (file) name of the attachment. */ -inline void AbstractAttachment::setName(const std::string &name) +inline void AbstractAttachment::setName(std::string_view name) { m_name = name; } @@ -188,7 +188,7 @@ inline const std::string &AbstractAttachment::mimeType() const /*! * \brief Sets the MIME-type of the attachment. */ -inline void AbstractAttachment::setMimeType(const std::string &mimeType) +inline void AbstractAttachment::setMimeType(std::string_view mimeType) { m_mimeType = mimeType; } @@ -204,7 +204,7 @@ inline std::uint64_t AbstractAttachment::id() const /*! * \brief Sets the ID of the attachment. */ -inline void AbstractAttachment::setId(const std::uint64_t &id) +inline void AbstractAttachment::setId(uint64_t id) { m_id = id; } diff --git a/abstractcontainer.h b/abstractcontainer.h index 2d0267b..31e97ac 100644 --- a/abstractcontainer.h +++ b/abstractcontainer.h @@ -76,7 +76,7 @@ public: std::uint64_t doctypeVersion() const; std::uint64_t doctypeReadVersion() const; const std::vector &titles() const; - void setTitle(const std::string &title, std::size_t segmentIndex = 0); + void setTitle(std::string_view title, std::size_t segmentIndex = 0); virtual bool supportsTitle() const; virtual std::size_t segmentCount() const; CppUtilities::TimeSpan duration() const; @@ -265,7 +265,7 @@ inline const std::vector &AbstractContainer::titles() const * \throws Throws out_of_range if the segment does not exist. * \sa titles() */ -inline void AbstractContainer::setTitle(const std::string &title, std::size_t segmentIndex) +inline void AbstractContainer::setTitle(std::string_view title, std::size_t segmentIndex) { m_titles.at(segmentIndex) = title; } diff --git a/abstracttrack.cpp b/abstracttrack.cpp index 37d3999..ecb5653 100644 --- a/abstracttrack.cpp +++ b/abstracttrack.cpp @@ -53,7 +53,6 @@ AbstractTrack::AbstractTrack(istream &inputStream, ostream &outputStream, std::u , m_quality(0) , m_depth(0) , m_fps(0) - , m_chromaFormat(nullptr) , m_timeScale(0) , m_colorSpace(0) { @@ -81,16 +80,16 @@ AbstractTrack::~AbstractTrack() /*! * \brief Returns a string with the channel configuration if available; otherwise returns nullptr. */ -const char *AbstractTrack::channelConfigString() const +std::string_view AbstractTrack::channelConfigString() const { switch (m_format.general) { case GeneralMediaFormat::Aac: - return m_channelConfig ? Mpeg4ChannelConfigs::channelConfigString(m_channelConfig) : nullptr; + return m_channelConfig ? Mpeg4ChannelConfigs::channelConfigString(m_channelConfig) : std::string_view(); case GeneralMediaFormat::Mpeg1Audio: case GeneralMediaFormat::Mpeg2Audio: return mpegChannelModeString(static_cast(m_channelConfig)); default: - return nullptr; + return std::string_view(); } } @@ -105,13 +104,13 @@ std::uint8_t AbstractTrack::extensionChannelConfig() const /*! * \brief Returns a string with the extension channel configuration if available; otherwise returns nullptr. */ -const char *AbstractTrack::extensionChannelConfigString() const +std::string_view AbstractTrack::extensionChannelConfigString() const { switch (m_format.general) { case GeneralMediaFormat::Aac: - return m_extensionChannelConfig ? Mpeg4ChannelConfigs::channelConfigString(m_extensionChannelConfig) : nullptr; + return m_extensionChannelConfig ? Mpeg4ChannelConfigs::channelConfigString(m_extensionChannelConfig) : std::string_view(); default: - return nullptr; + return std::string_view(); } } @@ -140,15 +139,15 @@ string AbstractTrack::makeDescription(bool verbose) const { // use abbreviated format const auto format = MediaFormat(m_format.general, verbose ? m_format.sub : 0, verbose ? m_format.extension : 0); - const char *formatName = format.shortAbbreviation(); - if (!formatName || !*formatName) { + auto formatName = format.shortAbbreviation(); + if (formatName.empty()) { // fall back to media type name if no abbreviation available formatName = mediaTypeName(); } // find additional info and level - const char *additionalInfoRef = nullptr; - string level; + auto additionalInfoRef = std::string_view(); + auto level = std::string(); switch (m_mediaType) { case MediaType::Video: if (!displaySize().isNull()) { @@ -178,13 +177,13 @@ string AbstractTrack::makeDescription(bool verbose) const return argsToString(formatName, '-', channelCount(), 'c', 'h'); } } else if (const auto &localeName = locale().someAbbreviatedName(); !localeName.empty()) { - additionalInfoRef = localeName.data(); + additionalInfoRef = localeName; } break; default:; } - if (additionalInfoRef) { + if (!additionalInfoRef.empty()) { return argsToString(formatName, level, '-', additionalInfoRef); } return argsToString(formatName, level); diff --git a/abstracttrack.h b/abstracttrack.h index 92c13ca..7485e53 100644 --- a/abstracttrack.h +++ b/abstracttrack.h @@ -16,6 +16,7 @@ #include #include +#include namespace TagParser { @@ -79,18 +80,18 @@ public: TrackFlags flags() const; MediaFormat format() const; double version() const; - const char *formatName() const; - const char *formatAbbreviation() const; + std::string_view formatName() const; + std::string_view formatAbbreviation() const; const std::string &formatId() const; MediaType mediaType() const; - const char *mediaTypeName() const; + std::string_view mediaTypeName() const; std::uint64_t size() const; std::uint32_t trackNumber() const; void setTrackNumber(std::uint32_t trackNumber); std::uint64_t id() const; void setId(std::uint64_t id); const std::string name() const; - void setName(const std::string &name); + void setName(std::string_view name); const CppUtilities::TimeSpan &duration() const; double bitrate() const; double maxBitrate() const; @@ -103,19 +104,19 @@ public: std::uint16_t bitsPerSample() const; std::uint16_t channelCount() const; std::uint8_t channelConfig() const; - const char *channelConfigString() const; + std::string_view channelConfigString() const; std::uint8_t extensionChannelConfig() const; - const char *extensionChannelConfigString() const; + std::string_view extensionChannelConfigString() const; std::uint64_t sampleCount() const; int quality() const; const Size &pixelSize() const; const Size &displaySize() const; const Size &resolution() const; const std::string &compressorName() const; - void setCompressorName(const std::string &compressorName); + void setCompressorName(std::string_view compressorName); std::uint16_t depth() const; std::uint32_t fps() const; - const char *chromaFormat() const; + std::string_view chromaFormat() const; const AspectRatio &pixelAspectRatio() const; bool isInterlaced() const; std::uint32_t timeScale() const; @@ -178,7 +179,7 @@ protected: std::string m_compressorName; std::uint16_t m_depth; std::uint32_t m_fps; - const char *m_chromaFormat; + std::string_view m_chromaFormat; AspectRatio m_pixelAspectRatio; std::uint32_t m_timeScale; std::uint32_t m_colorSpace; @@ -293,22 +294,21 @@ inline double AbstractTrack::version() const * \brief Returns the format of the track as C-style string if known; otherwise * returns the format abbreviation or an empty string. * \remarks - * - The caller must not free the returned string. * - The string might get invalidated when the track is (re)parsed. */ -inline const char *AbstractTrack::formatName() const +inline std::string_view AbstractTrack::formatName() const { - return m_format || m_formatName.empty() ? m_format.name() : m_formatName.c_str(); + return m_format || m_formatName.empty() ? m_format.name() : m_formatName; } /*! * \brief Returns the a more or less common abbreviation for the format of the track - * as C-style string if known; otherwise returns an empty string. + * if known; otherwise returns an empty string. */ -inline const char *AbstractTrack::formatAbbreviation() const +inline std::string_view AbstractTrack::formatAbbreviation() const { - const char *abbr = m_format.abbreviation(); - return *abbr || m_formatId.empty() ? m_format.abbreviation() : m_formatId.c_str(); + const auto abbr = m_format.abbreviation(); + return !abbr.empty() || m_formatId.empty() ? abbr : m_formatId; } /*! @@ -331,7 +331,7 @@ inline MediaType AbstractTrack::mediaType() const /*! * \brief Returns the string representation of the media type of the track. */ -inline const char *AbstractTrack::mediaTypeName() const +inline std::string_view AbstractTrack::mediaTypeName() const { return ::TagParser::mediaTypeName(m_mediaType); } @@ -390,7 +390,7 @@ inline const std::string AbstractTrack::name() const * \brief Sets the name. * \remarks Whether the new value is applied when saving changes depends on the implementation. */ -inline void AbstractTrack::setName(const std::string &name) +inline void AbstractTrack::setName(std::string_view name) { m_name = name; } @@ -560,7 +560,7 @@ inline const std::string &AbstractTrack::compressorName() const * \brief Returns the compressor name if known; otherwise returns an empty string. * \remarks Whether the new value is applied when saving changes depends on the implementation. */ -inline void AbstractTrack::setCompressorName(const std::string &compressorName) +inline void AbstractTrack::setCompressorName(std::string_view compressorName) { m_compressorName = compressorName; } @@ -588,7 +588,7 @@ inline std::uint32_t AbstractTrack::fps() const * * This value only makes sense for video tracks. */ -inline const char *AbstractTrack::chromaFormat() const +inline std::string_view AbstractTrack::chromaFormat() const { return m_chromaFormat; } diff --git a/backuphelper.cpp b/backuphelper.cpp index 8cbe541..0460738 100644 --- a/backuphelper.cpp +++ b/backuphelper.cpp @@ -68,7 +68,7 @@ void restoreOriginalFileFromBackupFile( } // remove original file and restore backup std::remove(originalPath.c_str()); - if (std::rename(BasicFileInfo::pathForOpen(backupPath), BasicFileInfo::pathForOpen(originalPath)) == 0) { + if (std::rename(BasicFileInfo::pathForOpen(backupPath).data(), BasicFileInfo::pathForOpen(originalPath).data()) == 0) { return; } // can't rename/move the file (maybe backup dir on another partition) -> make a copy instead @@ -154,10 +154,10 @@ void createBackupFile(const std::string &backupDir, const std::string &originalP // test whether the backup path is still unused; otherwise continue loop #ifdef PLATFORM_WINDOWS - if (GetFileAttributes(BasicFileInfo::pathForOpen(backupPath)) == INVALID_FILE_ATTRIBUTES) { + if (GetFileAttributes(BasicFileInfo::pathForOpen(backupPath).data()) == INVALID_FILE_ATTRIBUTES) { #else struct stat backupStat; - if (stat(BasicFileInfo::pathForOpen(backupPath), &backupStat)) { + if (stat(BasicFileInfo::pathForOpen(backupPath).data(), &backupStat)) { #endif break; } @@ -169,7 +169,7 @@ void createBackupFile(const std::string &backupDir, const std::string &originalP } // rename original file - if (std::rename(BasicFileInfo::pathForOpen(originalPath), BasicFileInfo::pathForOpen(backupPath))) { + if (std::rename(BasicFileInfo::pathForOpen(originalPath).data(), BasicFileInfo::pathForOpen(backupPath).data())) { // can't rename/move the file (maybe backup dir on another partition) -> make a copy instead try { backupStream.exceptions(ios_base::failbit | ios_base::badbit); @@ -178,9 +178,9 @@ void createBackupFile(const std::string &backupDir, const std::string &originalP if (backupStream.is_open()) { backupStream.close(); } - backupStream.open(BasicFileInfo::pathForOpen(backupPath), ios_base::out | ios_base::binary); + backupStream.open(BasicFileInfo::pathForOpen(backupPath).data(), ios_base::out | ios_base::binary); // ensure originalStream is opened with read permissions - originalStream.open(BasicFileInfo::pathForOpen(originalPath), ios_base::in | ios_base::binary); + originalStream.open(BasicFileInfo::pathForOpen(originalPath).data(), ios_base::in | ios_base::binary); // do the actual copying backupStream << originalStream.rdbuf(); backupStream.flush(); @@ -203,11 +203,11 @@ void createBackupFile(const std::string &backupDir, const std::string &originalP } // open backup stream backupStream.exceptions(ios_base::failbit | ios_base::badbit); - backupStream.open(BasicFileInfo::pathForOpen(backupPath), ios_base::in | ios_base::binary); + backupStream.open(BasicFileInfo::pathForOpen(backupPath).data(), ios_base::in | ios_base::binary); } catch (const std::ios_base::failure &failure) { // can't open the new file // -> try to re-rename backup file in the error case to restore previous state - if (std::rename(BasicFileInfo::pathForOpen(backupPath), BasicFileInfo::pathForOpen(originalPath))) { + if (std::rename(BasicFileInfo::pathForOpen(backupPath).data(), BasicFileInfo::pathForOpen(originalPath).data())) { throw std::ios_base::failure("Unable to restore original file from backup file \"" % backupPath % "\" after failure: " + failure.what()); } else { throw std::ios_base::failure(argsToString("Unable to open backup file: ", failure.what())); diff --git a/basicfileinfo.cpp b/basicfileinfo.cpp index 2a78267..65315c5 100644 --- a/basicfileinfo.cpp +++ b/basicfileinfo.cpp @@ -20,7 +20,7 @@ namespace TagParser { * * \param path Specifies the absolute or relative path of the file. */ -BasicFileInfo::BasicFileInfo(const std::string &path) +BasicFileInfo::BasicFileInfo(std::string_view path) : m_path(path) , m_size(0) , m_readOnly(false) @@ -59,7 +59,8 @@ void BasicFileInfo::open(bool readOnly) void BasicFileInfo::reopen(bool readOnly) { invalidated(); - m_file.open(pathForOpen(path()), (m_readOnly = readOnly) ? ios_base::in | ios_base::binary : ios_base::in | ios_base::out | ios_base::binary); + m_file.open( + pathForOpen(path()).data(), (m_readOnly = readOnly) ? ios_base::in | ios_base::binary : ios_base::in | ios_base::out | ios_base::binary); m_file.seekg(0, ios_base::end); m_size = static_cast(m_file.tellg()); m_file.seekg(0, ios_base::beg); @@ -91,7 +92,7 @@ void BasicFileInfo::invalidate() * * \param path Specifies the absolute or relative path of the file to be set. */ -void BasicFileInfo::setPath(const string &path) +void BasicFileInfo::setPath(std::string_view path) { if (path != m_path) { invalidated(); @@ -138,13 +139,13 @@ string BasicFileInfo::fileName(bool cutExtension) const * * \param path Specifies the path of the file. */ -string BasicFileInfo::extension(const string &path) +std::string BasicFileInfo::extension(std::string_view path) { - size_t lastPoint = path.rfind('.'); - if (lastPoint == string::npos) { - return string(); + std::size_t lastPoint = path.rfind('.'); + if (lastPoint == std::string::npos) { + return std::string(); } else { - return path.substr(lastPoint); + return std::string(path.data() + lastPoint, path.size() - lastPoint); } } diff --git a/basicfileinfo.h b/basicfileinfo.h index 6f69e56..2d25eea 100644 --- a/basicfileinfo.h +++ b/basicfileinfo.h @@ -14,7 +14,7 @@ namespace TagParser { class TAG_PARSER_EXPORT BasicFileInfo { public: // constructor, destructor - explicit BasicFileInfo(const std::string &path = std::string()); + explicit BasicFileInfo(std::string_view path = std::string_view()); BasicFileInfo(const BasicFileInfo &) = delete; BasicFileInfo &operator=(const BasicFileInfo &) = delete; virtual ~BasicFileInfo(); @@ -31,16 +31,16 @@ public: // methods to get, set path (components) const std::string &path() const; - void setPath(const std::string &path); + void setPath(std::string_view path); static std::string fileName(const std::string &path, bool cutExtension = false); std::string fileName(bool cutExtension = false) const; - static std::string extension(const std::string &path); + static std::string extension(std::string_view path); std::string extension() const; static std::string pathWithoutExtension(const std::string &fullPath); std::string pathWithoutExtension() const; static std::string containingDirectory(const std::string &path); std::string containingDirectory() const; - static const char *pathForOpen(const std::string &url); + static std::string_view pathForOpen(const std::string &url); // methods to get, set the file size std::uint64_t size() const; @@ -137,7 +137,7 @@ inline void BasicFileInfo::reportPathChanged(const std::string &newPath) * \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 const char *BasicFileInfo::pathForOpen(const std::string &url) +inline std::string_view BasicFileInfo::pathForOpen(const std::string &url) { return CppUtilities::startsWith(url, "file:/") ? url.data() + 6 : url.data(); } diff --git a/caseinsensitivecomparer.h b/caseinsensitivecomparer.h index fb3d475..2ab9b52 100644 --- a/caseinsensitivecomparer.h +++ b/caseinsensitivecomparer.h @@ -32,6 +32,10 @@ struct TAG_PARSER_EXPORT CaseInsensitiveStringComparer { { return std::lexicographical_compare(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend(), CaseInsensitiveCharComparer()); } + bool operator()(std::string_view lhs, std::string_view rhs) const + { + return std::lexicographical_compare(lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend(), CaseInsensitiveCharComparer()); + } }; } // namespace TagParser diff --git a/diagnostics.cpp b/diagnostics.cpp index 9aa7f6f..39e3336 100644 --- a/diagnostics.cpp +++ b/diagnostics.cpp @@ -19,7 +19,7 @@ namespace TagParser { /*! * \brief Returns the string representation of the specified \a diagLevel. */ -const char *diagLevelName(DiagLevel diagLevel) +std::string_view diagLevelName(DiagLevel diagLevel) { switch (diagLevel) { case DiagLevel::Information: @@ -32,7 +32,7 @@ const char *diagLevelName(DiagLevel diagLevel) return "debug"; case DiagLevel::None: default: - return ""; + return std::string_view(); } } diff --git a/diagnostics.h b/diagnostics.h index 4f03cb4..912c790 100644 --- a/diagnostics.h +++ b/diagnostics.h @@ -25,7 +25,7 @@ enum class DiagLevel { /// \brief The worst diag level. constexpr auto worstDiagLevel = DiagLevel::Fatal; -TAG_PARSER_EXPORT const char *diagLevelName(DiagLevel diagLevel); +TAG_PARSER_EXPORT std::string_view diagLevelName(DiagLevel diagLevel); /*! * \brief Sets \a lhs to \a rhs if \a rhs is more critical than \a lhs and returns \a lhs. @@ -46,7 +46,7 @@ public: DiagMessage(DiagLevel level, std::string &&message, std::string &&context); DiagLevel level() const; - const char *levelName() const; + std::string_view levelName() const; const std::string &message() const; const std::string &context() const; const CppUtilities::DateTime &creationTime() const; @@ -116,7 +116,7 @@ inline DiagLevel DiagMessage::level() const /*! * \brief Returns the string representation of the level(). */ -inline const char *DiagMessage::levelName() const +inline std::string_view DiagMessage::levelName() const { return diagLevelName(m_level); } diff --git a/fieldbasedtag.h b/fieldbasedtag.h index 39faea7..571e175 100644 --- a/fieldbasedtag.h +++ b/fieldbasedtag.h @@ -39,7 +39,7 @@ public: FieldMapBasedTag(); TagType type() const; - const char *typeName() const; + std::string_view typeName() const; TagTextEncoding proposedTextEncoding() const; const TagValue &value(const IdentifierType &id) const; const TagValue &value(KnownField field) const; @@ -107,7 +107,7 @@ template TagType FieldMapBasedTag return ImplementationType::tagType; } -template const char *FieldMapBasedTag::typeName() const +template std::string_view FieldMapBasedTag::typeName() const { return ImplementationType::tagName; } diff --git a/flac/flacmetadata.cpp b/flac/flacmetadata.cpp index feb958e..f788f99 100644 --- a/flac/flacmetadata.cpp +++ b/flac/flacmetadata.cpp @@ -26,11 +26,11 @@ namespace TagParser { * \brief Parses the FLAC "METADATA_BLOCK_HEADER" which is read using the specified \a iterator. * \remarks The specified \a buffer must be at least 4 bytes long. */ -void FlacMetaDataBlockHeader::parseHeader(const char *buffer) +void FlacMetaDataBlockHeader::parseHeader(std::string_view buffer) { - m_last = *buffer & 0x80; - m_type = *buffer & (0x80 - 1); - m_dataSize = BE::toUInt24(buffer + 1); + m_last = buffer[0] & 0x80; + m_type = buffer[0] & (0x80 - 1); + m_dataSize = BE::toUInt24(buffer.data() + 1); } /*! @@ -55,9 +55,9 @@ void FlacMetaDataBlockHeader::makeHeader(std::ostream &outputStream) * \brief Parses the FLAC "METADATA_BLOCK_STREAMINFO" which is read using the specified \a iterator. * \remarks The specified \a buffer must be at least 0x22 bytes long. */ -void FlacMetaDataBlockStreamInfo::parse(const char *buffer) +void FlacMetaDataBlockStreamInfo::parse(std::string_view buffer) { - BitReader reader(buffer, 0x22); + auto reader = BitReader(buffer.data(), 0x22); m_minBlockSize = reader.readBits(16); m_maxBlockSize = reader.readBits(16); m_minFrameSize = reader.readBits(24); @@ -66,7 +66,7 @@ void FlacMetaDataBlockStreamInfo::parse(const char *buffer) m_channelCount = reader.readBits(3) + 1; m_bitsPerSample = reader.readBits(5) + 1; m_totalSampleCount = reader.readBits(36); - memcpy(m_md5Sum, buffer + 0x22 - sizeof(m_md5Sum), sizeof(m_md5Sum)); + std::memcpy(m_md5Sum, buffer.data() + 0x22 - sizeof(m_md5Sum), sizeof(m_md5Sum)); } /*! diff --git a/flac/flacmetadata.h b/flac/flacmetadata.h index 551322d..b1f64a3 100644 --- a/flac/flacmetadata.h +++ b/flac/flacmetadata.h @@ -29,7 +29,7 @@ class TAG_PARSER_EXPORT FlacMetaDataBlockHeader { public: constexpr FlacMetaDataBlockHeader(); - void parseHeader(const char *buffer); + void parseHeader(std::string_view buffer); void makeHeader(std::ostream &outputStream); constexpr std::uint8_t isLast() const; @@ -110,7 +110,7 @@ class TAG_PARSER_EXPORT FlacMetaDataBlockStreamInfo { public: constexpr FlacMetaDataBlockStreamInfo(); - void parse(const char *buffer); + void parse(std::string_view buffer); constexpr std::uint16_t minBlockSize() const; constexpr std::uint16_t maxBlockSize() const; diff --git a/id3/id3genres.cpp b/id3/id3genres.cpp index 336267b..d3ab9fc 100644 --- a/id3/id3genres.cpp +++ b/id3/id3genres.cpp @@ -12,9 +12,9 @@ namespace TagParser { /*! * \brief Returns all known genre names. */ -const char *const *Id3Genres::genreNames() +const std::string_view *Id3Genres::genreNames() { - static const char *const names[] = { "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", + static const std::string_view names[] = { "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", @@ -39,12 +39,12 @@ const char *const *Id3Genres::genreNames() * \brief Returns the numerical denotation of the specified \a genre or -1 if \a genre is unknown. * \remarks If \a string is empty, the non-standard Id3Genres::emptyGenreIndex() is returned. */ -int Id3Genres::indexFromString(const string &genre) +int Id3Genres::indexFromString(std::string_view genre) { if (genre.empty()) { return emptyGenreIndex(); } - const char *const *ptr = genreNames(); + const string_view *ptr = genreNames(); for (int index = 0; index < genreCount(); ++ptr, ++index) { if (genre == *ptr) { return index; diff --git a/id3/id3genres.h b/id3/id3genres.h index 1672b90..b491671 100644 --- a/id3/id3genres.h +++ b/id3/id3genres.h @@ -4,29 +4,29 @@ #include "../global.h" #include -#include +#include namespace TagParser { class TAG_PARSER_EXPORT Id3Genres { public: - static inline const char *stringFromIndex(int index); - static int indexFromString(const std::string &genre); + static inline std::string_view stringFromIndex(int index); + static int indexFromString(std::string_view genre); static constexpr int genreCount(); static constexpr int emptyGenreIndex(); static constexpr bool isEmptyGenre(int index); static constexpr bool isIndexSupported(int index); private: - static const char *const *genreNames(); + static const std::string_view *genreNames(); }; /*! * \brief Returns the genre name for the specified numerical denotation as C-style string. */ -inline const char *Id3Genres::stringFromIndex(int index) +inline std::string_view Id3Genres::stringFromIndex(int index) { - return isIndexSupported(index) ? genreNames()[index] : nullptr; + return isIndexSupported(index) ? genreNames()[index] : std::string_view(); } /*! diff --git a/id3/id3v1tag.cpp b/id3/id3v1tag.cpp index 3111764..c93b0b8 100644 --- a/id3/id3v1tag.cpp +++ b/id3/id3v1tag.cpp @@ -32,7 +32,7 @@ TagType Id3v1Tag::type() const return TagType::Id3v1Tag; } -const char *Id3v1Tag::typeName() const +std::string_view Id3v1Tag::typeName() const { return tagName; } diff --git a/id3/id3v1tag.h b/id3/id3v1tag.h index a99104f..ee25e3b 100644 --- a/id3/id3v1tag.h +++ b/id3/id3v1tag.h @@ -12,9 +12,9 @@ public: Id3v1Tag(); static constexpr TagType tagType = TagType::Id3v1Tag; - static constexpr const char *tagName = "ID3v1 tag"; + static constexpr std::string_view tagName = "ID3v1 tag"; TagType type() const override; - const char *typeName() const override; + std::string_view typeName() const override; bool canEncodingBeUsed(TagTextEncoding encoding) const override; const TagValue &value(KnownField value) const override; bool setValue(KnownField field, const TagValue &value) override; diff --git a/id3/id3v2frame.h b/id3/id3v2frame.h index c789732..1589913 100644 --- a/id3/id3v2frame.h +++ b/id3/id3v2frame.h @@ -140,7 +140,7 @@ public: static void makeComment( std::unique_ptr &buffer, std::uint32_t &bufferSize, const TagValue &comment, std::uint8_t version, Diagnostics &diag); - static IdentifierType fieldIdFromString(const char *idString, std::size_t idStringSize = std::string::npos); + static IdentifierType fieldIdFromString(std::string_view idString); static std::string fieldIdToString(IdentifierType id); private: @@ -332,13 +332,13 @@ inline bool Id3v2Frame::supportsNestedFields() const /*! * \brief Converts the specified ID string representation to an actual ID. */ -inline Id3v2Frame::IdentifierType Id3v2Frame::fieldIdFromString(const char *idString, std::size_t idStringSize) +inline Id3v2Frame::IdentifierType Id3v2Frame::fieldIdFromString(std::string_view idString) { - switch (idStringSize != std::string::npos ? idStringSize : std::strlen(idString)) { + switch (idString.size()) { case 3: - return CppUtilities::BE::toUInt24(idString); + return CppUtilities::BE::toUInt24(idString.data()); case 4: - return CppUtilities::BE::toUInt32(idString); + return CppUtilities::BE::toUInt32(idString.data()); default: throw CppUtilities::ConversionException("ID3v2 ID must be 3 or 4 chars"); } diff --git a/id3/id3v2tag.h b/id3/id3v2tag.h index 01aa883..fb1feec 100644 --- a/id3/id3v2tag.h +++ b/id3/id3v2tag.h @@ -66,7 +66,7 @@ public: Id3v2Tag(); static constexpr TagType tagType = TagType::Id3v2Tag; - static constexpr const char *tagName = "ID3v2 tag"; + static constexpr std::string_view tagName = "ID3v2 tag"; static constexpr TagTextEncoding defaultTextEncoding = TagTextEncoding::Utf16LittleEndian; TagTextEncoding proposedTextEncoding() const override; bool canEncodingBeUsed(TagTextEncoding encoding) const override; diff --git a/matroska/ebmlelement.cpp b/matroska/ebmlelement.cpp index ce35067..f71994b 100644 --- a/matroska/ebmlelement.cpp +++ b/matroska/ebmlelement.cpp @@ -528,31 +528,14 @@ void EbmlElement::makeSimpleElement(ostream &stream, IdentifierType id, std::uin * \param id Specifies the element ID. * \param content Specifies the value of the element as string. */ -void EbmlElement::makeSimpleElement(std::ostream &stream, GenericFileElement::IdentifierType id, const std::string &content) +void EbmlElement::makeSimpleElement(std::ostream &stream, GenericFileElement::IdentifierType id, string_view content) { char buff1[8]; std::uint8_t sizeLength = EbmlElement::makeId(id, buff1); stream.write(buff1, sizeLength); sizeLength = EbmlElement::makeSizeDenotation(content.size(), buff1); stream.write(buff1, sizeLength); - stream.write(content.c_str(), content.size()); -} - -/*! - * \brief Makes a simple EBML element. - * \param stream Specifies the stream to write the data to. - * \param id Specifies the element ID. - * \param data Specifies the data of the element. - * \param dataSize Specifies the size of \a data. - */ -void EbmlElement::makeSimpleElement(ostream &stream, GenericFileElement::IdentifierType id, const char *data, std::size_t dataSize) -{ - char buff1[8]; - std::uint8_t sizeLength = EbmlElement::makeId(id, buff1); - stream.write(buff1, sizeLength); - sizeLength = EbmlElement::makeSizeDenotation(dataSize, buff1); - stream.write(buff1, sizeLength); - stream.write(data, dataSize); + stream.write(content.data(), content.size()); } } // namespace TagParser diff --git a/matroska/ebmlelement.h b/matroska/ebmlelement.h index 24715b0..f780714 100644 --- a/matroska/ebmlelement.h +++ b/matroska/ebmlelement.h @@ -12,6 +12,7 @@ #include #include #include +#include namespace TagParser { @@ -51,8 +52,7 @@ public: static std::uint8_t makeUInteger(std::uint64_t value, char *buff); static std::uint8_t makeUInteger(std::uint64_t value, char *buff, std::uint8_t minBytes); static void makeSimpleElement(std::ostream &stream, IdentifierType id, std::uint64_t content); - static void makeSimpleElement(std::ostream &stream, IdentifierType id, const std::string &content); - static void makeSimpleElement(std::ostream &stream, IdentifierType id, const char *data, std::size_t dataSize); + static void makeSimpleElement(std::ostream &stream, IdentifierType id, std::string_view content); static std::uint64_t bytesToBeSkipped; protected: @@ -71,8 +71,7 @@ private: inline std::string EbmlElement::idToString() const { using namespace CppUtilities; - const char *const name = matroskaIdName(id()); - if (*name) { + if (const auto name = matroskaIdName(id()); !name.empty()) { return argsToString('0', 'x', numberToString(id(), 16), ' ', '\"', name, '\"'); } else { return "0x" + numberToString(id(), 16); diff --git a/matroska/matroskacontainer.cpp b/matroska/matroskacontainer.cpp index 3960e6e..98940ac 100644 --- a/matroska/matroskacontainer.cpp +++ b/matroska/matroskacontainer.cpp @@ -923,13 +923,12 @@ void MatroskaContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFee const std::uint64_t ebmlHeaderSize = 4 + EbmlElement::calculateSizeDenotationLength(ebmlHeaderDataSize) + ebmlHeaderDataSize; // calculate size of "WritingLib"-element - constexpr const char muxingAppName[] = APP_NAME " v" APP_VERSION; - constexpr std::uint64_t muxingAppElementDataSize = sizeof(muxingAppName) - 1; - constexpr std::uint64_t muxingAppElementTotalSize = 2 + 1 + muxingAppElementDataSize; + constexpr std::string_view muxingAppName = APP_NAME " v" APP_VERSION; + constexpr std::uint64_t muxingAppElementTotalSize = 2 + 1 + muxingAppName.size(); // calculate size of "WritingApp"-element const std::uint64_t writingAppElementDataSize - = fileInfo().writingApplication().empty() ? muxingAppElementDataSize : fileInfo().writingApplication().size() - 1; + = fileInfo().writingApplication().empty() ? muxingAppName.size() : fileInfo().writingApplication().size(); const std::uint64_t writingAppElementTotalSize = 2 + 1 + writingAppElementDataSize; try { @@ -1496,7 +1495,7 @@ void MatroskaContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFee try { BackupHelper::createBackupFile(fileInfo().backupDirectory(), fileInfo().path(), backupPath, outputStream, backupStream); // recreate original file, define buffer variables - outputStream.open(BasicFileInfo::pathForOpen(fileInfo().path()), ios_base::out | ios_base::binary | ios_base::trunc); + outputStream.open(BasicFileInfo::pathForOpen(fileInfo().path()).data(), ios_base::out | ios_base::binary | ios_base::trunc); } catch (const std::ios_base::failure &failure) { diag.emplace_back( DiagLevel::Critical, argsToString("Creation of temporary file (to rewrite the original file) failed: ", failure.what()), context); @@ -1506,9 +1505,9 @@ void MatroskaContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFee // open the current file as backupStream and create a new outputStream at the specified "save file path" try { backupStream.exceptions(ios_base::badbit | ios_base::failbit); - backupStream.open(BasicFileInfo::pathForOpen(fileInfo().path()), ios_base::in | ios_base::binary); + backupStream.open(BasicFileInfo::pathForOpen(fileInfo().path()).data(), ios_base::in | ios_base::binary); fileInfo().close(); - outputStream.open(BasicFileInfo::pathForOpen(fileInfo().saveFilePath()), ios_base::out | ios_base::binary | ios_base::trunc); + outputStream.open(BasicFileInfo::pathForOpen(fileInfo().saveFilePath()).data(), ios_base::out | ios_base::binary | ios_base::trunc); } catch (const std::ios_base::failure &failure) { diag.emplace_back(DiagLevel::Critical, argsToString("Opening streams to write output file failed: ", failure.what()), context); throw; @@ -1618,9 +1617,9 @@ void MatroskaContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFee } } // -> write "MuxingApp"- and "WritingApp"-element - EbmlElement::makeSimpleElement(outputStream, MatroskaIds::MuxingApp, muxingAppName, muxingAppElementDataSize); + EbmlElement::makeSimpleElement(outputStream, MatroskaIds::MuxingApp, muxingAppName); EbmlElement::makeSimpleElement(outputStream, MatroskaIds::WrittingApp, - fileInfo().writingApplication().empty() ? muxingAppName : fileInfo().writingApplication().data(), writingAppElementDataSize); + fileInfo().writingApplication().empty() ? muxingAppName : fileInfo().writingApplication()); } // write "Tracks"-element diff --git a/matroska/matroskaid.cpp b/matroska/matroskaid.cpp index a0cca63..b3d2e15 100644 --- a/matroska/matroskaid.cpp +++ b/matroska/matroskaid.cpp @@ -19,7 +19,7 @@ namespace MatroskaTrackType { * \brief Returns a string for the specified \a matroskaId * if known; otherwise returns an empty string. */ -const char *matroskaIdName(std::uint32_t matroskaId) +std::string_view matroskaIdName(std::uint32_t matroskaId) { using namespace EbmlIds; using namespace MatroskaIds; @@ -518,7 +518,7 @@ const char *matroskaIdName(std::uint32_t matroskaId) return "reference time code"; default: - return ""; + return std::string_view(); } } diff --git a/matroska/matroskaid.h b/matroska/matroskaid.h index 4f0806d..20b0299 100644 --- a/matroska/matroskaid.h +++ b/matroska/matroskaid.h @@ -4,6 +4,7 @@ #include "../global.h" #include +#include namespace TagParser { @@ -448,7 +449,7 @@ constexpr bool operator<=(MatroskaElementLevel lhs, MatroskaElementLevel rhs) return lhs == rhs || lhs < rhs; } -TAG_PARSER_EXPORT const char *matroskaIdName(std::uint32_t matroskaId); +TAG_PARSER_EXPORT std::string_view matroskaIdName(std::uint32_t matroskaId); TAG_PARSER_EXPORT MatroskaElementLevel matroskaIdLevel(std::uint32_t matroskaId); } // namespace TagParser diff --git a/matroska/matroskatag.cpp b/matroska/matroskatag.cpp index f806237..25b9a58 100644 --- a/matroska/matroskatag.cpp +++ b/matroska/matroskatag.cpp @@ -4,8 +4,8 @@ #include "../diagnostics.h" #include -#include #include +#include using namespace std; using namespace CppUtilities; @@ -22,59 +22,59 @@ MatroskaTag::IdentifierType MatroskaTag::internallyGetFieldId(KnownField field) using namespace MatroskaTagIds; switch (field) { case KnownField::Artist: - return artist(); + return std::string(artist()); case KnownField::Album: - return album(); + return std::string(album()); case KnownField::Comment: - return comment(); + return std::string(comment()); case KnownField::RecordDate: case KnownField::Year: - return dateRecorded(); + return std::string(dateRecorded()); case KnownField::ReleaseDate: - return dateRelease(); + return std::string(dateRelease()); case KnownField::Title: - return title(); + return std::string(title()); case KnownField::Genre: - return genre(); + return std::string(genre()); case KnownField::PartNumber: - return partNumber(); + return std::string(partNumber()); case KnownField::TotalParts: - return totalParts(); + return std::string(totalParts()); case KnownField::Encoder: - return encoder(); + return std::string(encoder()); case KnownField::EncoderSettings: - return encoderSettings(); + return std::string(encoderSettings()); case KnownField::Bpm: - return bpm(); + return std::string(bpm()); case KnownField::Bps: - return bps(); + return std::string(bps()); case KnownField::Rating: - return rating(); + return std::string(rating()); case KnownField::Description: - return description(); + return std::string(description()); case KnownField::Lyrics: - return lyrics(); + return std::string(lyrics()); case KnownField::RecordLabel: - return label(); + return std::string(label()); case KnownField::Performers: - return actor(); + return std::string(actor()); case KnownField::Lyricist: - return lyricist(); + return std::string(lyricist()); case KnownField::Composer: - return composer(); + return std::string(composer()); case KnownField::Length: - return duration(); + return std::string(duration()); case KnownField::Language: - return language(); + return std::string(language()); default: - return string(); + return std::string(); } } KnownField MatroskaTag::internallyGetKnownField(const IdentifierType &id) const { using namespace MatroskaTagIds; - static const map fieldMap({ + static const std::unordered_map fieldMap({ { artist(), KnownField::Artist }, { album(), KnownField::Album }, { comment(), KnownField::Comment }, diff --git a/matroska/matroskatag.h b/matroska/matroskatag.h index 8fcddce..65db999 100644 --- a/matroska/matroskatag.h +++ b/matroska/matroskatag.h @@ -62,7 +62,7 @@ public: MatroskaTag(); static constexpr TagType tagType = TagType::MatroskaTag; - static constexpr const char *tagName = "Matroska tag"; + static constexpr std::string_view tagName = "Matroska tag"; static constexpr TagTextEncoding defaultTextEncoding = TagTextEncoding::Utf8; bool canEncodingBeUsed(TagTextEncoding encoding) const override; bool supportsTarget() const override; diff --git a/matroska/matroskatagfield.h b/matroska/matroskatagfield.h index 545df03..6f2a72d 100644 --- a/matroska/matroskatagfield.h +++ b/matroska/matroskatagfield.h @@ -77,7 +77,7 @@ public: bool isAdditionalTypeInfoUsed() const; bool supportsNestedFields() const; - static typename std::string fieldIdFromString(const char *idString, std::size_t idStringSize = std::string::npos); + static typename std::string fieldIdFromString(std::string_view idString); static std::string fieldIdToString(const std::string &id); }; @@ -101,9 +101,9 @@ inline bool MatroskaTagField::supportsNestedFields() const * \brief Converts the specified ID string representation to an actual ID. * \remarks As Matroska field IDs are text strings the string is just passed. */ -inline std::string MatroskaTagField::fieldIdFromString(const char *idString, std::size_t idStringSize) +inline std::string MatroskaTagField::fieldIdFromString(std::string_view idString) { - return idStringSize != std::string::npos ? std::string(idString, idStringSize) : std::string(idString); + return std::string(idString); } /*! diff --git a/matroska/matroskatagid.h b/matroska/matroskatagid.h index db69750..f224f4a 100644 --- a/matroska/matroskatagid.h +++ b/matroska/matroskatagid.h @@ -3,469 +3,471 @@ #include "../tagtarget.h" +#include + namespace TagParser { namespace MatroskaTagIds { -constexpr TAG_PARSER_EXPORT const char *original() +constexpr TAG_PARSER_EXPORT std::string_view original() { return "ORIGINAL"; } -constexpr TAG_PARSER_EXPORT const char *sample() +constexpr TAG_PARSER_EXPORT std::string_view sample() { return "SAMPLE"; } -constexpr TAG_PARSER_EXPORT const char *country() +constexpr TAG_PARSER_EXPORT std::string_view country() { return "COUNTRY"; } -constexpr TAG_PARSER_EXPORT const char *totalParts() +constexpr TAG_PARSER_EXPORT std::string_view totalParts() { return "TOTAL_PARTS"; } -constexpr TAG_PARSER_EXPORT const char *partNumber() +constexpr TAG_PARSER_EXPORT std::string_view partNumber() { return "PART_NUMBER"; } -constexpr TAG_PARSER_EXPORT const char *partOffset() +constexpr TAG_PARSER_EXPORT std::string_view partOffset() { return "PART_OFFSET"; } -constexpr TAG_PARSER_EXPORT const char *title() +constexpr TAG_PARSER_EXPORT std::string_view title() { return "TITLE"; } -constexpr TAG_PARSER_EXPORT const char *subtitle() +constexpr TAG_PARSER_EXPORT std::string_view subtitle() { return "SUBTITLE"; } -constexpr TAG_PARSER_EXPORT const char *url() +constexpr TAG_PARSER_EXPORT std::string_view url() { return "URL"; } -constexpr TAG_PARSER_EXPORT const char *sortWith() +constexpr TAG_PARSER_EXPORT std::string_view sortWith() { return "SORT_WITH"; } -constexpr TAG_PARSER_EXPORT const char *instruments() +constexpr TAG_PARSER_EXPORT std::string_view instruments() { return "INSTRUMENTS"; } -constexpr TAG_PARSER_EXPORT const char *email() +constexpr TAG_PARSER_EXPORT std::string_view email() { return "EMAIL"; } -constexpr TAG_PARSER_EXPORT const char *address() +constexpr TAG_PARSER_EXPORT std::string_view address() { return "ADDRESS"; } -constexpr TAG_PARSER_EXPORT const char *fax() +constexpr TAG_PARSER_EXPORT std::string_view fax() { return "FAX"; } -constexpr TAG_PARSER_EXPORT const char *phone() +constexpr TAG_PARSER_EXPORT std::string_view phone() { return "PHONE"; } -constexpr TAG_PARSER_EXPORT const char *artist() +constexpr TAG_PARSER_EXPORT std::string_view artist() { return "ARTIST"; } -constexpr TAG_PARSER_EXPORT const char *album() +constexpr TAG_PARSER_EXPORT std::string_view album() { return "ALBUM"; } -constexpr TAG_PARSER_EXPORT const char *leadPerformer() +constexpr TAG_PARSER_EXPORT std::string_view leadPerformer() { return "LEAD_PERFORMER"; } -constexpr TAG_PARSER_EXPORT const char *accompaniment() +constexpr TAG_PARSER_EXPORT std::string_view accompaniment() { return "ACCOMPANIMENT"; } -constexpr TAG_PARSER_EXPORT const char *composer() +constexpr TAG_PARSER_EXPORT std::string_view composer() { return "COMPOSER"; } -constexpr TAG_PARSER_EXPORT const char *arranger() +constexpr TAG_PARSER_EXPORT std::string_view arranger() { return "ARRANGER"; } -constexpr TAG_PARSER_EXPORT const char *lyrics() +constexpr TAG_PARSER_EXPORT std::string_view lyrics() { return "LYRICS"; } -constexpr TAG_PARSER_EXPORT const char *lyricist() +constexpr TAG_PARSER_EXPORT std::string_view lyricist() { return "LYRICIST"; } -constexpr TAG_PARSER_EXPORT const char *conductor() +constexpr TAG_PARSER_EXPORT std::string_view conductor() { return "CONDUCTOR"; } -constexpr TAG_PARSER_EXPORT const char *director() +constexpr TAG_PARSER_EXPORT std::string_view director() { return "DIRECTOR"; } -constexpr TAG_PARSER_EXPORT const char *assistantDirector() +constexpr TAG_PARSER_EXPORT std::string_view assistantDirector() { return "ASSISTANT_DIRECTOR"; } -constexpr TAG_PARSER_EXPORT const char *directorOfPhotography() +constexpr TAG_PARSER_EXPORT std::string_view directorOfPhotography() { return "DIRECTOR_OF_PHOTOGRAPHY"; } -constexpr TAG_PARSER_EXPORT const char *soundEngineer() +constexpr TAG_PARSER_EXPORT std::string_view soundEngineer() { return "SOUND_ENGINEER"; } -constexpr TAG_PARSER_EXPORT const char *artDirector() +constexpr TAG_PARSER_EXPORT std::string_view artDirector() { return "ART_DIRECTOR"; } -constexpr TAG_PARSER_EXPORT const char *productionDesigner() +constexpr TAG_PARSER_EXPORT std::string_view productionDesigner() { return "PRODUCTION_DESIGNER"; } -constexpr TAG_PARSER_EXPORT const char *choregrapher() +constexpr TAG_PARSER_EXPORT std::string_view choregrapher() { return "CHOREGRAPHER"; } -constexpr TAG_PARSER_EXPORT const char *costumeDesigner() +constexpr TAG_PARSER_EXPORT std::string_view costumeDesigner() { return "COSTUME_DESIGNER"; } -constexpr TAG_PARSER_EXPORT const char *actor() +constexpr TAG_PARSER_EXPORT std::string_view actor() { return "ACTOR"; } -constexpr TAG_PARSER_EXPORT const char *character() +constexpr TAG_PARSER_EXPORT std::string_view character() { return "CHARACTER"; } -constexpr TAG_PARSER_EXPORT const char *writtenBy() +constexpr TAG_PARSER_EXPORT std::string_view writtenBy() { return "WRITTEN_BY"; } -constexpr TAG_PARSER_EXPORT const char *screenplayBy() +constexpr TAG_PARSER_EXPORT std::string_view screenplayBy() { return "SCREENPLAY_BY"; } -constexpr TAG_PARSER_EXPORT const char *editedBy() +constexpr TAG_PARSER_EXPORT std::string_view editedBy() { return "EDITED_BY"; } -constexpr TAG_PARSER_EXPORT const char *producer() +constexpr TAG_PARSER_EXPORT std::string_view producer() { return "PRODUCER"; } -constexpr TAG_PARSER_EXPORT const char *coproducer() +constexpr TAG_PARSER_EXPORT std::string_view coproducer() { return "COPRODUCER"; } -constexpr TAG_PARSER_EXPORT const char *executiveProducer() +constexpr TAG_PARSER_EXPORT std::string_view executiveProducer() { return "EXECUTIVE_PRODUCER"; } -constexpr TAG_PARSER_EXPORT const char *distributedBy() +constexpr TAG_PARSER_EXPORT std::string_view distributedBy() { return "DISTRIBUTED_BY"; } -constexpr TAG_PARSER_EXPORT const char *masteredBy() +constexpr TAG_PARSER_EXPORT std::string_view masteredBy() { return "MASTERED_BY"; } -constexpr TAG_PARSER_EXPORT const char *encodedBy() +constexpr TAG_PARSER_EXPORT std::string_view encodedBy() { return "ENCODED_BY"; } -constexpr TAG_PARSER_EXPORT const char *mixedBy() +constexpr TAG_PARSER_EXPORT std::string_view mixedBy() { return "MIXED_BY"; } -constexpr TAG_PARSER_EXPORT const char *remixedBy() +constexpr TAG_PARSER_EXPORT std::string_view remixedBy() { return "REMIXED_BY"; } -constexpr TAG_PARSER_EXPORT const char *productionStudio() +constexpr TAG_PARSER_EXPORT std::string_view productionStudio() { return "PRODUCTION_STUDIO"; } -constexpr TAG_PARSER_EXPORT const char *thanksTo() +constexpr TAG_PARSER_EXPORT std::string_view thanksTo() { return "THANKS_TO"; } -constexpr TAG_PARSER_EXPORT const char *publisher() +constexpr TAG_PARSER_EXPORT std::string_view publisher() { return "PUBLISHER"; } -constexpr TAG_PARSER_EXPORT const char *label() +constexpr TAG_PARSER_EXPORT std::string_view label() { return "LABEL"; } -constexpr TAG_PARSER_EXPORT const char *genre() +constexpr TAG_PARSER_EXPORT std::string_view genre() { return "GENRE"; } -constexpr TAG_PARSER_EXPORT const char *mood() +constexpr TAG_PARSER_EXPORT std::string_view mood() { return "MOOD"; } -constexpr TAG_PARSER_EXPORT const char *originalMediaType() +constexpr TAG_PARSER_EXPORT std::string_view originalMediaType() { return "ORIGINAL_TAG_PARSER_TYPE"; } -constexpr TAG_PARSER_EXPORT const char *contentType() +constexpr TAG_PARSER_EXPORT std::string_view contentType() { return "CONTENT_TYPE"; } -constexpr TAG_PARSER_EXPORT const char *subject() +constexpr TAG_PARSER_EXPORT std::string_view subject() { return "SUBJECT"; } -constexpr TAG_PARSER_EXPORT const char *description() +constexpr TAG_PARSER_EXPORT std::string_view description() { return "DESCRIPTION"; } -constexpr TAG_PARSER_EXPORT const char *keywords() +constexpr TAG_PARSER_EXPORT std::string_view keywords() { return "KEYWORDS"; } -constexpr TAG_PARSER_EXPORT const char *summary() +constexpr TAG_PARSER_EXPORT std::string_view summary() { return "SUMMARY"; } -constexpr TAG_PARSER_EXPORT const char *synopsis() +constexpr TAG_PARSER_EXPORT std::string_view synopsis() { return "SYNOPSIS"; } -constexpr TAG_PARSER_EXPORT const char *initialKey() +constexpr TAG_PARSER_EXPORT std::string_view initialKey() { return "INITIAL_KEY"; } -constexpr TAG_PARSER_EXPORT const char *period() +constexpr TAG_PARSER_EXPORT std::string_view period() { return "PERIOD"; } -constexpr TAG_PARSER_EXPORT const char *lawRating() +constexpr TAG_PARSER_EXPORT std::string_view lawRating() { return "LAW_RATING"; } -constexpr TAG_PARSER_EXPORT const char *icra() +constexpr TAG_PARSER_EXPORT std::string_view icra() { return "ICRA"; } -constexpr TAG_PARSER_EXPORT const char *dateRelease() +constexpr TAG_PARSER_EXPORT std::string_view dateRelease() { return "DATE_RELEASED"; } -constexpr TAG_PARSER_EXPORT const char *dateRecorded() +constexpr TAG_PARSER_EXPORT std::string_view dateRecorded() { return "DATE_RECORDED"; } -constexpr TAG_PARSER_EXPORT const char *dateEncoded() +constexpr TAG_PARSER_EXPORT std::string_view dateEncoded() { return "DATE_ENCODED"; } -constexpr TAG_PARSER_EXPORT const char *dateTagged() +constexpr TAG_PARSER_EXPORT std::string_view dateTagged() { return "DATE_TAGGED"; } -constexpr TAG_PARSER_EXPORT const char *dateDigitized() +constexpr TAG_PARSER_EXPORT std::string_view dateDigitized() { return "DATE_DIGITIZED"; } -constexpr TAG_PARSER_EXPORT const char *dateWritten() +constexpr TAG_PARSER_EXPORT std::string_view dateWritten() { return "DATE_WRITTEN"; } -constexpr TAG_PARSER_EXPORT const char *datePurchased() +constexpr TAG_PARSER_EXPORT std::string_view datePurchased() { return "DATE_PURCHASED"; } -constexpr TAG_PARSER_EXPORT const char *recordingLocation() +constexpr TAG_PARSER_EXPORT std::string_view recordingLocation() { return "RECORDING_LOCATION"; } -constexpr TAG_PARSER_EXPORT const char *compositionLocation() +constexpr TAG_PARSER_EXPORT std::string_view compositionLocation() { return "COMPOSITION_LOCATION"; } -constexpr TAG_PARSER_EXPORT const char *composerNationality() +constexpr TAG_PARSER_EXPORT std::string_view composerNationality() { return "COMPOSER_NATIONALITY"; } -constexpr TAG_PARSER_EXPORT const char *comment() +constexpr TAG_PARSER_EXPORT std::string_view comment() { return "COMMENT"; } -constexpr TAG_PARSER_EXPORT const char *playCounter() +constexpr TAG_PARSER_EXPORT std::string_view playCounter() { return "PLAY_COUNTER"; } -constexpr TAG_PARSER_EXPORT const char *rating() +constexpr TAG_PARSER_EXPORT std::string_view rating() { return "RATING"; } -constexpr TAG_PARSER_EXPORT const char *encoder() +constexpr TAG_PARSER_EXPORT std::string_view encoder() { return "ENCODER"; } -constexpr TAG_PARSER_EXPORT const char *encoderSettings() +constexpr TAG_PARSER_EXPORT std::string_view encoderSettings() { return "ENCODER_SETTINGS"; } -constexpr TAG_PARSER_EXPORT const char *bps() +constexpr TAG_PARSER_EXPORT std::string_view bps() { return "BPS"; } -constexpr TAG_PARSER_EXPORT const char *fps() +constexpr TAG_PARSER_EXPORT std::string_view fps() { return "FPS"; } -constexpr TAG_PARSER_EXPORT const char *bpm() +constexpr TAG_PARSER_EXPORT std::string_view bpm() { return "BPM"; } -constexpr TAG_PARSER_EXPORT const char *duration() +constexpr TAG_PARSER_EXPORT std::string_view duration() { return "DURATION"; } -constexpr TAG_PARSER_EXPORT const char *language() +constexpr TAG_PARSER_EXPORT std::string_view language() { return "LANGUAGE"; } -constexpr TAG_PARSER_EXPORT const char *numberOfFrames() +constexpr TAG_PARSER_EXPORT std::string_view numberOfFrames() { return "NUMBER_OF_FRAMES"; } -constexpr TAG_PARSER_EXPORT const char *numberOfBytes() +constexpr TAG_PARSER_EXPORT std::string_view numberOfBytes() { return "NUMBER_OF_BYTES"; } -constexpr TAG_PARSER_EXPORT const char *measure() +constexpr TAG_PARSER_EXPORT std::string_view measure() { return "MEASURE"; } -constexpr TAG_PARSER_EXPORT const char *tuning() +constexpr TAG_PARSER_EXPORT std::string_view tuning() { return "TUNING"; } -constexpr TAG_PARSER_EXPORT const char *replaygainGain() +constexpr TAG_PARSER_EXPORT std::string_view replaygainGain() { return "REPLAYGAIN_GAIN"; } -constexpr TAG_PARSER_EXPORT const char *replaygainPeak() +constexpr TAG_PARSER_EXPORT std::string_view replaygainPeak() { return "REPLAYGAIN_PEAK"; } -constexpr TAG_PARSER_EXPORT const char *identifiers() +constexpr TAG_PARSER_EXPORT std::string_view identifiers() { return "Identifiers"; } -constexpr TAG_PARSER_EXPORT const char *isrc() +constexpr TAG_PARSER_EXPORT std::string_view isrc() { return "ISRC"; } -constexpr TAG_PARSER_EXPORT const char *mcdi() +constexpr TAG_PARSER_EXPORT std::string_view mcdi() { return "MCDI"; } -constexpr TAG_PARSER_EXPORT const char *isbn() +constexpr TAG_PARSER_EXPORT std::string_view isbn() { return "ISBN"; } -constexpr TAG_PARSER_EXPORT const char *barcode() +constexpr TAG_PARSER_EXPORT std::string_view barcode() { return "BARCODE"; } -constexpr TAG_PARSER_EXPORT const char *catalogNumber() +constexpr TAG_PARSER_EXPORT std::string_view catalogNumber() { return "CATALOG_NUMBER"; } -constexpr TAG_PARSER_EXPORT const char *labelCode() +constexpr TAG_PARSER_EXPORT std::string_view labelCode() { return "LABEL_CODE"; } -constexpr TAG_PARSER_EXPORT const char *lccn() +constexpr TAG_PARSER_EXPORT std::string_view lccn() { return "LCCN"; } -constexpr TAG_PARSER_EXPORT const char *purchaseItem() +constexpr TAG_PARSER_EXPORT std::string_view purchaseItem() { return "PURCHASE_ITEM"; } -constexpr TAG_PARSER_EXPORT const char *purchaseInfo() +constexpr TAG_PARSER_EXPORT std::string_view purchaseInfo() { return "PURCHASE_INFO"; } -constexpr TAG_PARSER_EXPORT const char *purchaseOwner() +constexpr TAG_PARSER_EXPORT std::string_view purchaseOwner() { return "PURCHASE_OWNER"; } -constexpr TAG_PARSER_EXPORT const char *purchasePrice() +constexpr TAG_PARSER_EXPORT std::string_view purchasePrice() { return "PURCHASE_PRICE"; } -constexpr TAG_PARSER_EXPORT const char *purchaseCurrency() +constexpr TAG_PARSER_EXPORT std::string_view purchaseCurrency() { return "PURCHASE_CURRENCY"; } -constexpr TAG_PARSER_EXPORT const char *copyright() +constexpr TAG_PARSER_EXPORT std::string_view copyright() { return "COPYRIGHT"; } -constexpr TAG_PARSER_EXPORT const char *productionCopyright() +constexpr TAG_PARSER_EXPORT std::string_view productionCopyright() { return "PRODUCTION_COPYRIGHT"; } -constexpr TAG_PARSER_EXPORT const char *license() +constexpr TAG_PARSER_EXPORT std::string_view license() { return "LICENSE"; } -constexpr TAG_PARSER_EXPORT const char *termsOfUse() +constexpr TAG_PARSER_EXPORT std::string_view termsOfUse() { return "TERMS_OF_USE"; } namespace TrackSpecific { -constexpr TAG_PARSER_EXPORT const char *numberOfBytes() +constexpr TAG_PARSER_EXPORT std::string_view numberOfBytes() { return "NUMBER_OF_BYTES"; } -constexpr TAG_PARSER_EXPORT const char *numberOfFrames() +constexpr TAG_PARSER_EXPORT std::string_view numberOfFrames() { return "NUMBER_OF_FRAMES"; } -constexpr TAG_PARSER_EXPORT const char *duration() +constexpr TAG_PARSER_EXPORT std::string_view duration() { return "DURATION"; } /// \brief The track's bit rate in bits per second. -constexpr TAG_PARSER_EXPORT const char *bitrate() +constexpr TAG_PARSER_EXPORT std::string_view bitrate() { return "BPS"; } -constexpr TAG_PARSER_EXPORT const char *writingApp() +constexpr TAG_PARSER_EXPORT std::string_view writingApp() { return "_STATISTICS_WRITING_APP"; } -constexpr TAG_PARSER_EXPORT const char *writingDate() +constexpr TAG_PARSER_EXPORT std::string_view writingDate() { return "_STATISTICS_WRITING_DATE_UTC"; } -constexpr TAG_PARSER_EXPORT const char *statisticsTags() +constexpr TAG_PARSER_EXPORT std::string_view statisticsTags() { return "_STATISTICS_TAGS"; } diff --git a/matroska/matroskatrack.cpp b/matroska/matroskatrack.cpp index e74edb7..782836e 100644 --- a/matroska/matroskatrack.cpp +++ b/matroska/matroskatrack.cpp @@ -212,10 +212,10 @@ MediaFormat MatroskaTrack::codecIdToMediaFormat(const string &codecId) /// \cond template -void MatroskaTrack::assignPropertyFromTagValue(const std::unique_ptr &tag, const char *fieldId, PropertyType &property, +void MatroskaTrack::assignPropertyFromTagValue(const std::unique_ptr &tag, std::string_view fieldId, PropertyType &property, const ConversionFunction &conversionFunction, Diagnostics &diag) { - const TagValue &value = tag->value(fieldId); + const TagValue &value = tag->value(std::string(fieldId)); if (!value.isEmpty()) { try { property = conversionFunction(value); diff --git a/matroska/matroskatrack.h b/matroska/matroskatrack.h index afd1204..43336a9 100644 --- a/matroska/matroskatrack.h +++ b/matroska/matroskatrack.h @@ -65,7 +65,7 @@ protected: private: template - void assignPropertyFromTagValue(const std::unique_ptr &tag, const char *fieldId, PropertyType &integer, + void assignPropertyFromTagValue(const std::unique_ptr &tag, std::string_view fieldId, PropertyType &integer, const ConversionFunction &conversionFunction, Diagnostics &diag); EbmlElement *m_trackElement; diff --git a/mediafileinfo.cpp b/mediafileinfo.cpp index 2630291..562f859 100644 --- a/mediafileinfo.cpp +++ b/mediafileinfo.cpp @@ -734,7 +734,7 @@ void MediaFileInfo::applyChanges(Diagnostics &diag, AbortableProgressFeedback &p * \sa containerFormatName() * \sa parseContainerFormat() */ -const char *MediaFileInfo::containerFormatAbbreviation() const +string_view MediaFileInfo::containerFormatAbbreviation() const { MediaType mediaType = MediaType::Unknown; unsigned int version = 0; @@ -788,7 +788,7 @@ const char *MediaFileInfo::containerFormatAbbreviation() const * \sa containerFormatName() * \sa parseContainerFormat() */ -const char *MediaFileInfo::mimeType() const +string_view MediaFileInfo::mimeType() const { MediaType mediaType; switch (m_containerFormat) { @@ -1531,7 +1531,7 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr } progress.updateStep("Removing ID3v1 tag ..."); stream().close(); - if (truncate(BasicFileInfo::pathForOpen(path()), static_cast(size() - 128)) == 0) { + if (truncate(BasicFileInfo::pathForOpen(path()).data(), static_cast(size() - 128)) == 0) { reportSizeChanged(size() - 128); } else { diag.emplace_back(DiagLevel::Critical, "Unable to truncate file to remove ID3v1 tag.", context); @@ -1647,7 +1647,7 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr try { BackupHelper::createBackupFile(backupDirectory(), path(), backupPath, outputStream, backupStream); // recreate original file, define buffer variables - outputStream.open(BasicFileInfo::pathForOpen(path()), ios_base::out | ios_base::binary | ios_base::trunc); + outputStream.open(BasicFileInfo::pathForOpen(path()).data(), ios_base::out | ios_base::binary | ios_base::trunc); } catch (const std::ios_base::failure &failure) { diag.emplace_back( DiagLevel::Critical, argsToString("Creation of temporary file (to rewrite the original file) failed: ", failure.what()), context); @@ -1658,8 +1658,8 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr try { close(); backupStream.exceptions(ios_base::badbit | ios_base::failbit); - backupStream.open(BasicFileInfo::pathForOpen(path()), ios_base::in | ios_base::binary); - outputStream.open(BasicFileInfo::pathForOpen(m_saveFilePath), ios_base::out | ios_base::binary | ios_base::trunc); + backupStream.open(BasicFileInfo::pathForOpen(path()).data(), ios_base::in | ios_base::binary); + outputStream.open(BasicFileInfo::pathForOpen(m_saveFilePath).data(), ios_base::out | ios_base::binary | ios_base::trunc); } catch (const std::ios_base::failure &failure) { diag.emplace_back(DiagLevel::Critical, argsToString("Opening streams to write output file failed: ", failure.what()), context); throw; @@ -1670,7 +1670,7 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr // reopen original file to ensure it is opened for writing try { close(); - outputStream.open(BasicFileInfo::pathForOpen(path()), ios_base::in | ios_base::out | ios_base::binary); + outputStream.open(BasicFileInfo::pathForOpen(path()).data(), ios_base::in | ios_base::out | ios_base::binary); } catch (const std::ios_base::failure &failure) { diag.emplace_back(DiagLevel::Critical, argsToString("Opening the file with write permissions failed: ", failure.what()), context); throw; @@ -1776,7 +1776,7 @@ void MediaFileInfo::makeMp3File(Diagnostics &diag, AbortableProgressFeedback &pr // -> prevent deferring final write operations outputStream.close(); // -> truncate file - if (truncate(BasicFileInfo::pathForOpen(path()), static_cast(newSize)) == 0) { + if (truncate(BasicFileInfo::pathForOpen(path()).data(), static_cast(newSize)) == 0) { reportSizeChanged(newSize); } else { diag.emplace_back(DiagLevel::Critical, "Unable to truncate the file.", context); diff --git a/mediafileinfo.h b/mediafileinfo.h index 652ba4e..0cc9de4 100644 --- a/mediafileinfo.h +++ b/mediafileinfo.h @@ -65,10 +65,10 @@ public: // methods to get parsed information regarding ... // ... the container ContainerFormat containerFormat() const; - const char *containerFormatName() const; - const char *containerFormatAbbreviation() const; - const char *containerFormatSubversion() const; - const char *mimeType() const; + std::string_view containerFormatName() const; + std::string_view containerFormatAbbreviation() const; + std::string_view containerFormatSubversion() const; + std::string_view mimeType() const; std::uint64_t containerOffset() const; std::uint64_t paddingSize() const; AbstractContainer *container() const; @@ -126,9 +126,8 @@ public: void setBackupDirectory(const std::string &backupDirectory); const std::string &saveFilePath() const; void setSaveFilePath(const std::string &saveFilePath); - const std::string writingApplication() const; - void setWritingApplication(const std::string &writingApplication); - void setWritingApplication(const char *writingApplication); + const std::string &writingApplication() const; + void setWritingApplication(std::string_view writingApplication); bool isForcingFullParse() const; void setForceFullParse(bool forceFullParse); bool isForcingRewrite() const; @@ -223,7 +222,7 @@ inline ContainerFormat MediaFileInfo::containerFormat() const * \sa containerFormatAbbreviation() * \sa parseContainerFormat() */ -inline const char *MediaFileInfo::containerFormatName() const +inline std::string_view MediaFileInfo::containerFormatName() const { return TagParser::containerFormatName(m_containerFormat); } @@ -238,7 +237,7 @@ inline const char *MediaFileInfo::containerFormatName() const * \sa containerFormatName() * \sa parseContainerFormat() */ -inline const char *MediaFileInfo::containerFormatSubversion() const +inline std::string_view MediaFileInfo::containerFormatSubversion() const { return TagParser::containerFormatSubversion(m_containerFormat); } @@ -396,7 +395,7 @@ inline void MediaFileInfo::setSaveFilePath(const std::string &saveFilePath) * \remarks This is not read from the file when parsing and only used when saving changes. * \sa setWritingApplication() for more details */ -inline const std::string MediaFileInfo::writingApplication() const +inline const std::string &MediaFileInfo::writingApplication() const { return m_writingApplication; } @@ -405,16 +404,7 @@ inline const std::string MediaFileInfo::writingApplication() const * \brief Sets the writing application as container-level meta-data. Put the name of your application here. * \remarks Might not be used (depends on the format). */ -inline void MediaFileInfo::setWritingApplication(const std::string &writingApplication) -{ - m_writingApplication = writingApplication; -} - -/*! - * \brief Sets the writing application as container-level meta-data. Put the name of your application here. - * \remarks Might not be used (depends on the format). - */ -inline void MediaFileInfo::setWritingApplication(const char *writingApplication) +inline void MediaFileInfo::setWritingApplication(std::string_view writingApplication) { m_writingApplication = writingApplication; } diff --git a/mediaformat.cpp b/mediaformat.cpp index c5b0302..fcf97a0 100644 --- a/mediaformat.cpp +++ b/mediaformat.cpp @@ -14,7 +14,7 @@ using namespace SubFormats; * * Returns an empty string if no name is available. */ -const char *MediaFormat::name() const +std::string_view MediaFormat::name() const { switch (general) { case GeneralMediaFormat::Aac: @@ -443,7 +443,7 @@ const char *MediaFormat::name() const * * Returns an empty string if no abbreviation is available. */ -const char *MediaFormat::abbreviation() const +std::string_view MediaFormat::abbreviation() const { switch (general) { case GeneralMediaFormat::Aac: @@ -758,7 +758,7 @@ const char *MediaFormat::abbreviation() const * * Returns an empty string if no abbreviation is available. */ -const char *MediaFormat::shortAbbreviation() const +std::string_view MediaFormat::shortAbbreviation() const { switch (general) { case GeneralMediaFormat::Aac: @@ -1033,7 +1033,7 @@ const char *MediaFormat::shortAbbreviation() const * * Returns an empty string if no abbreviation is available. */ -const char *MediaFormat::extensionName() const +std::string_view MediaFormat::extensionName() const { switch (general) { using namespace ExtensionFormats; @@ -1056,7 +1056,7 @@ const char *MediaFormat::extensionName() const /*! * \brief Returns the string representation for the specified \a mediaType. */ -const char *mediaTypeName(MediaType mediaType) +std::string_view mediaTypeName(MediaType mediaType) { switch (mediaType) { case MediaType::Unknown: diff --git a/mediaformat.h b/mediaformat.h index 2ca9e41..7fe3c8e 100644 --- a/mediaformat.h +++ b/mediaformat.h @@ -3,6 +3,7 @@ #include "./global.h" +#include #include namespace TagParser { @@ -21,7 +22,7 @@ enum class MediaType : unsigned int { Meta, /**< (timed) metadata */ }; -TAG_PARSER_EXPORT const char *mediaTypeName(MediaType mediaType); +TAG_PARSER_EXPORT std::string_view mediaTypeName(MediaType mediaType); /*! * \brief The GeneralMediaFormat enum specifies the general format of media data (PCM, MPEG-4, PNG, ...). @@ -246,10 +247,10 @@ class TAG_PARSER_EXPORT MediaFormat { public: constexpr MediaFormat(GeneralMediaFormat general = GeneralMediaFormat::Unknown, unsigned char sub = 0, unsigned char extension = 0); - const char *name() const; - const char *abbreviation() const; - const char *shortAbbreviation() const; - const char *extensionName() const; + std::string_view name() const; + std::string_view abbreviation() const; + std::string_view shortAbbreviation() const; + std::string_view extensionName() const; constexpr operator bool() const; constexpr MediaFormat &operator+=(const MediaFormat &other); constexpr bool operator==(GeneralMediaFormat general) const; diff --git a/mp4/mp4container.cpp b/mp4/mp4container.cpp index 3042356..959bbb1 100644 --- a/mp4/mp4container.cpp +++ b/mp4/mp4container.cpp @@ -516,7 +516,7 @@ calculatePadding: try { BackupHelper::createBackupFile(fileInfo().backupDirectory(), fileInfo().path(), backupPath, outputStream, backupStream); // recreate original file, define buffer variables - outputStream.open(BasicFileInfo::pathForOpen(fileInfo().path()), ios_base::out | ios_base::binary | ios_base::trunc); + outputStream.open(BasicFileInfo::pathForOpen(fileInfo().path()).data(), ios_base::out | ios_base::binary | ios_base::trunc); } catch (const std::ios_base::failure &failure) { diag.emplace_back( DiagLevel::Critical, argsToString("Creation of temporary file (to rewrite the original file) failed: ", failure.what()), context); @@ -526,9 +526,9 @@ calculatePadding: // open the current file as backupStream and create a new outputStream at the specified "save file path" try { backupStream.exceptions(ios_base::badbit | ios_base::failbit); - backupStream.open(BasicFileInfo::pathForOpen(fileInfo().path()), ios_base::in | ios_base::binary); + backupStream.open(BasicFileInfo::pathForOpen(fileInfo().path()).data(), ios_base::in | ios_base::binary); fileInfo().close(); - outputStream.open(BasicFileInfo::pathForOpen(fileInfo().saveFilePath()), ios_base::out | ios_base::binary | ios_base::trunc); + outputStream.open(BasicFileInfo::pathForOpen(fileInfo().saveFilePath()).data(), ios_base::out | ios_base::binary | ios_base::trunc); } catch (const std::ios_base::failure &failure) { diag.emplace_back(DiagLevel::Critical, argsToString("Opening streams to write output file failed: ", failure.what()), context); throw; @@ -819,7 +819,7 @@ calculatePadding: } // the outputStream needs to be reopened to be able to read again outputStream.close(); - outputStream.open(BasicFileInfo::pathForOpen(fileInfo().path()), ios_base::in | ios_base::out | ios_base::binary); + outputStream.open(BasicFileInfo::pathForOpen(fileInfo().path()).data(), ios_base::in | ios_base::out | ios_base::binary); setStream(outputStream); } else { const auto newSize = static_cast(outputStream.tellp()); @@ -828,13 +828,13 @@ calculatePadding: // -> close stream before truncating outputStream.close(); // -> truncate file - if (truncate(BasicFileInfo::pathForOpen(fileInfo().path()), static_cast(newSize)) == 0) { + if (truncate(BasicFileInfo::pathForOpen(fileInfo().path()).data(), static_cast(newSize)) == 0) { fileInfo().reportSizeChanged(newSize); } else { diag.emplace_back(DiagLevel::Critical, "Unable to truncate the file.", context); } // -> reopen the stream again - outputStream.open(BasicFileInfo::pathForOpen(fileInfo().path()), ios_base::in | ios_base::out | ios_base::binary); + outputStream.open(BasicFileInfo::pathForOpen(fileInfo().path()).data(), ios_base::in | ios_base::out | ios_base::binary); } else { // file is longer after the modification -> just report new size fileInfo().reportSizeChanged(newSize); diff --git a/mp4/mp4ids.cpp b/mp4/mp4ids.cpp index 1257736..9d4f4f3 100644 --- a/mp4/mp4ids.cpp +++ b/mp4/mp4ids.cpp @@ -21,15 +21,15 @@ namespace Mp4TagAtomIds { * \brief Encapsulates "mean values" used in iTunes style MP4 tags. */ namespace Mp4TagExtendedMeanIds { -const char *iTunes = "com.apple.iTunes"; +std::string_view iTunes = "com.apple.iTunes"; } /*! * \brief Encapsulates "name values" used in iTunes style MP4 tags. */ namespace Mp4TagExtendedNameIds { -const char *cdec = "cdec"; -const char *label = "LABEL"; +std::string_view cdec = "cdec"; +std::string_view label = "LABEL"; } // namespace Mp4TagExtendedNameIds /*! @@ -322,7 +322,7 @@ namespace Mpeg4ElementaryStreamTypeIds { /*! * \brief Returns the name of the stream type denoted by the specified MPEG-4 stream type ID. */ -const char *streamTypeName(std::uint8_t streamTypeId) +std::string_view streamTypeName(std::uint8_t streamTypeId) { switch (streamTypeId) { case ObjectDescriptor: @@ -430,7 +430,7 @@ namespace Mpeg4ChannelConfigs { /*! * \brief Returns the string representation for the specified MPEG-4 channel config. */ -const char *channelConfigString(std::uint8_t config) +std::string_view channelConfigString(std::uint8_t config) { switch (config) { case AotSpecificConfig: diff --git a/mp4/mp4ids.h b/mp4/mp4ids.h index 77c4a2f..f59e410 100644 --- a/mp4/mp4ids.h +++ b/mp4/mp4ids.h @@ -4,6 +4,7 @@ #include "../global.h" #include +#include namespace TagParser { @@ -124,12 +125,12 @@ enum KnownValue : std::uint32_t { } namespace Mp4TagExtendedMeanIds { -extern const char *iTunes; +extern std::string_view iTunes; } namespace Mp4TagExtendedNameIds { -extern const char *cdec; -extern const char *label; +extern std::string_view cdec; +extern std::string_view label; } // namespace Mp4TagExtendedNameIds namespace Mp4MediaTypeIds { @@ -508,7 +509,7 @@ enum KnownValue : std::uint8_t { StreamingText }; -TAG_PARSER_EXPORT const char *streamTypeName(std::uint8_t streamTypeId); +TAG_PARSER_EXPORT std::string_view streamTypeName(std::uint8_t streamTypeId); } // namespace Mpeg4ElementaryStreamTypeIds @@ -623,7 +624,7 @@ enum Mpeg4ChannelConfig : std::uint8_t { FrontCenterFrontLeftFrontRightSideLeftSideRightBackLeftBackRightLFEChannel }; -TAG_PARSER_EXPORT const char *channelConfigString(std::uint8_t config); +TAG_PARSER_EXPORT std::string_view channelConfigString(std::uint8_t config); TAG_PARSER_EXPORT std::uint8_t channelCount(std::uint8_t config); } // namespace Mpeg4ChannelConfigs diff --git a/mp4/mp4tag.cpp b/mp4/mp4tag.cpp index 713e3c8..ccc9a41 100644 --- a/mp4/mp4tag.cpp +++ b/mp4/mp4tag.cpp @@ -35,10 +35,7 @@ Mp4ExtendedFieldId::Mp4ExtendedFieldId(KnownField field) name = Mp4TagExtendedNameIds::label; updateOnly = true; // set record label via extended field only if extended field is already present break; - default: - mean = nullptr; - name = nullptr; - updateOnly = false; + default:; } } @@ -109,7 +106,7 @@ std::vector Mp4Tag::values(KnownField field) const * \remarks * - If there are multiple fields with specified \a mean and \a name only the first value will be returned. */ -const TagValue &Mp4Tag::value(const char *mean, const char *name) const +const TagValue &Mp4Tag::value(std::string_view mean, std::string_view name) const { auto range = fields().equal_range(Mp4TagAtomIds::Extended); for (auto i = range.first; i != range.second; ++i) { @@ -301,7 +298,7 @@ bool Mp4Tag::setValues(KnownField field, const std::vector &values) * - If no field is present, a new one will be created. * - If \a value is empty, the field will be removed. */ -bool Mp4Tag::setValue(const char *mean, const char *name, const TagValue &value) +bool Mp4Tag::setValue(std::string_view mean, std::string_view name, const TagValue &value) { auto range = fields().equal_range(Mp4TagAtomIds::Extended); for (auto i = range.first; i != range.second; ++i) { diff --git a/mp4/mp4tag.h b/mp4/mp4tag.h index bbbb9b8..587bf47 100644 --- a/mp4/mp4tag.h +++ b/mp4/mp4tag.h @@ -11,24 +11,24 @@ class Mp4Atom; class Mp4Tag; struct TAG_PARSER_EXPORT Mp4ExtendedFieldId { - Mp4ExtendedFieldId(const char *mean = nullptr, const char *name = nullptr, bool updateOnly = false); + Mp4ExtendedFieldId(std::string_view mean, std::string_view name, bool updateOnly = false); Mp4ExtendedFieldId(KnownField field); operator bool() const; bool matches(const Mp4TagField &field) const; /// \brief mean parameter, usually Mp4TagExtendedMeanIds::iTunes - const char *mean; + std::string_view mean; /// \brief name parameter - const char *name; + std::string_view name; /// \brief Whether only existing fields should be updated but *no* new extended field should be created - bool updateOnly; + bool updateOnly = false; }; /*! * \brief Constructs a new instance with the specified parameter. */ -inline Mp4ExtendedFieldId::Mp4ExtendedFieldId(const char *mean, const char *name, bool updateOnly) +inline Mp4ExtendedFieldId::Mp4ExtendedFieldId(std::string_view mean, std::string_view name, bool updateOnly) : mean(mean) , name(name) , updateOnly(updateOnly) @@ -40,7 +40,7 @@ inline Mp4ExtendedFieldId::Mp4ExtendedFieldId(const char *mean, const char *name */ inline Mp4ExtendedFieldId::operator bool() const { - return mean && name; + return !mean.empty() && !name.empty(); } /*! @@ -101,7 +101,7 @@ public: Mp4Tag(); static constexpr TagType tagType = TagType::Mp4Tag; - static constexpr const char *tagName = "MP4/iTunes tag"; + static constexpr std::string_view tagName = "MP4/iTunes tag"; static constexpr TagTextEncoding defaultTextEncoding = TagTextEncoding::Utf8; bool canEncodingBeUsed(TagTextEncoding encoding) const override; @@ -110,14 +110,12 @@ public: const TagValue &value(KnownField value) const override; using FieldMapBasedTag::values; std::vector values(KnownField field) const override; - const TagValue &value(const std::string &mean, const std::string &name) const; - const TagValue &value(const char *mean, const char *name) const; + const TagValue &value(std::string_view mean, std::string_view name) const; using FieldMapBasedTag::setValue; bool setValue(KnownField field, const TagValue &value) override; using FieldMapBasedTag::setValues; bool setValues(KnownField field, const std::vector &values) override; - bool setValue(const std::string &mean, const std::string &name, const TagValue &value); - bool setValue(const char *mean, const char *name, const TagValue &value); + bool setValue(std::string_view mean, std::string_view name, const TagValue &value); using FieldMapBasedTag::hasField; bool hasField(KnownField value) const override; bool supportsMultipleValues(KnownField) const override; @@ -149,22 +147,6 @@ inline bool Mp4Tag::supportsField(KnownField field) const } } -/*! - * \brief Returns the value of the field with the specified \a mean and \a name attributes. - */ -inline const TagValue &Mp4Tag::value(const std::string &mean, const std::string &name) const -{ - return value(mean.data(), name.data()); -} - -/*! - * \brief Assigns the given \a value to the field with the specified \a mean and \a name attributes. - */ -inline bool Mp4Tag::setValue(const std::string &mean, const std::string &name, const TagValue &value) -{ - return setValue(mean.data(), name.data(), value); -} - /*! * \brief Returns false for all fields (for now). * \remarks Not sure whether iTunes-style MP4 tags allow this. Let's return false for now. diff --git a/mp4/mp4tagfield.cpp b/mp4/mp4tagfield.cpp index e9effd6..555d787 100644 --- a/mp4/mp4tagfield.cpp +++ b/mp4/mp4tagfield.cpp @@ -53,7 +53,7 @@ Mp4TagField::Mp4TagField(IdentifierType id, const TagValue &value) * \sa The last paragraph of Known iTunes Metadata Atoms * gives additional information about this form of MP4 tag fields. */ -Mp4TagField::Mp4TagField(const string &mean, const string &name, const TagValue &value) +Mp4TagField::Mp4TagField(std::string_view mean, std::string_view name, const TagValue &value) : Mp4TagField(Mp4TagAtomIds::Extended, value) { m_name = name; diff --git a/mp4/mp4tagfield.h b/mp4/mp4tagfield.h index b478110..2b6e0a0 100644 --- a/mp4/mp4tagfield.h +++ b/mp4/mp4tagfield.h @@ -122,7 +122,7 @@ public: Mp4TagField(); Mp4TagField(IdentifierType id, const TagValue &value); - Mp4TagField(const std::string &mean, const std::string &name, const TagValue &value); + Mp4TagField(std::string_view mean, std::string_view name, const TagValue &value); void reparse(Mp4Atom &ilstChild, Diagnostics &diag); Mp4TagFieldMaker prepareMaking(Diagnostics &diag); @@ -143,7 +143,7 @@ public: std::uint32_t appropriateRawDataType() const; std::uint32_t appropriateRawDataTypeForValue(const TagValue &value) const; - static IdentifierType fieldIdFromString(const char *idString, std::size_t idStringSize = std::string::npos); + static IdentifierType fieldIdFromString(std::string_view idString); static std::string fieldIdToString(IdentifierType id); private: @@ -252,9 +252,9 @@ inline bool Mp4TagField::supportsNestedFields() const * \remarks The specified \a idString is assumed to be UTF-8 encoded. In order to get the ©-sign * correctly, it is converted to Latin-1. */ -inline Mp4TagField::IdentifierType Mp4TagField::fieldIdFromString(const char *idString, std::size_t idStringSize) +inline Mp4TagField::IdentifierType Mp4TagField::fieldIdFromString(std::string_view idString) { - const auto latin1 = CppUtilities::convertUtf8ToLatin1(idString, idStringSize != std::string::npos ? idStringSize : std::strlen(idString)); + const auto latin1 = CppUtilities::convertUtf8ToLatin1(idString.data(), idString.size()); switch (latin1.second) { case 4: return CppUtilities::BE::toUInt32(latin1.first.get()); diff --git a/mpegaudio/mpegaudioframe.cpp b/mpegaudio/mpegaudioframe.cpp index 78b6b17..ebcea3a 100644 --- a/mpegaudio/mpegaudioframe.cpp +++ b/mpegaudio/mpegaudioframe.cpp @@ -14,7 +14,7 @@ namespace TagParser { /*! * \brief Returns the string representation for the specified \a channelMode. */ -const char *mpegChannelModeString(MpegChannelMode channelMode) +std::string_view mpegChannelModeString(MpegChannelMode channelMode) { switch (channelMode) { case MpegChannelMode::Stereo: diff --git a/mpegaudio/mpegaudioframe.h b/mpegaudio/mpegaudioframe.h index 81a6cca..0f032f4 100644 --- a/mpegaudio/mpegaudioframe.h +++ b/mpegaudio/mpegaudioframe.h @@ -5,6 +5,7 @@ #include #include +#include namespace CppUtilities { class BinaryReader; @@ -23,7 +24,7 @@ enum class MpegChannelMode { Unspecifed /**< used to indicate that the channel mode is unknown */ }; -TAG_PARSER_EXPORT const char *mpegChannelModeString(MpegChannelMode channelMode); +TAG_PARSER_EXPORT std::string_view mpegChannelModeString(MpegChannelMode channelMode); enum class XingHeaderFlags { None = 0x0u, /**< No Xing frames are present */ diff --git a/ogg/oggcontainer.cpp b/ogg/oggcontainer.cpp index 0b44129..a9aeb34 100644 --- a/ogg/oggcontainer.cpp +++ b/ogg/oggcontainer.cpp @@ -21,7 +21,7 @@ namespace TagParser { * \brief Specialization of TagParser::VorbisComment for Vorbis comments inside an OGG stream. */ -const char *OggVorbisComment::typeName() const +std::string_view OggVorbisComment::typeName() const { switch (m_oggParams.streamFormat) { case GeneralMediaFormat::Flac: @@ -376,7 +376,7 @@ void OggContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFeedback try { BackupHelper::createBackupFile(fileInfo().backupDirectory(), fileInfo().path(), backupPath, fileInfo().stream(), backupStream); // recreate original file, define buffer variables - fileInfo().stream().open(BasicFileInfo::pathForOpen(fileInfo().path()), ios_base::out | ios_base::binary | ios_base::trunc); + fileInfo().stream().open(BasicFileInfo::pathForOpen(fileInfo().path()).data(), ios_base::out | ios_base::binary | ios_base::trunc); } catch (const std::ios_base::failure &failure) { diag.emplace_back( DiagLevel::Critical, argsToString("Creation of temporary file (to rewrite the original file) failed: ", failure.what()), context); @@ -386,9 +386,10 @@ void OggContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFeedback // open the current file as backupStream and create a new outputStream at the specified "save file path" try { backupStream.exceptions(ios_base::badbit | ios_base::failbit); - backupStream.open(BasicFileInfo::pathForOpen(fileInfo().path()), ios_base::in | ios_base::binary); + backupStream.open(BasicFileInfo::pathForOpen(fileInfo().path()).data(), ios_base::in | ios_base::binary); fileInfo().close(); - fileInfo().stream().open(BasicFileInfo::pathForOpen(fileInfo().saveFilePath()), ios_base::out | ios_base::binary | ios_base::trunc); + fileInfo().stream().open( + BasicFileInfo::pathForOpen(fileInfo().saveFilePath()).data(), ios_base::out | ios_base::binary | ios_base::trunc); } catch (const std::ios_base::failure &failure) { diag.emplace_back(DiagLevel::Critical, argsToString("Opening streams to write output file failed: ", failure.what()), context); throw; diff --git a/ogg/oggcontainer.h b/ogg/oggcontainer.h index ed0714d..e36b6b4 100644 --- a/ogg/oggcontainer.h +++ b/ogg/oggcontainer.h @@ -71,9 +71,9 @@ public: OggVorbisComment(); static constexpr TagType tagType = TagType::OggVorbisComment; - static constexpr const char *tagName = "OGG Vorbis comment"; + static constexpr std::string_view tagName = "OGG Vorbis comment"; TagType type() const override; - const char *typeName() const override; + std::string_view typeName() const override; bool supportsTarget() const override; OggParameter &oggParams(); diff --git a/signature.cpp b/signature.cpp index cbd119f..557947b 100644 --- a/signature.cpp +++ b/signature.cpp @@ -101,17 +101,17 @@ enum Sig16 : std::uint16_t { * \return Returns the container format denoted by the signature. If the * signature is unknown ContainerFormat::Unknown is returned. */ -ContainerFormat parseSignature(const char *buffer, int bufferSize) +ContainerFormat parseSignature(std::string_view buffer) { // read signature std::uint64_t sig = 0; - if (bufferSize >= 8) { - sig = BE::toUInt64(buffer); - } else if (bufferSize >= 4) { - sig = BE::toUInt32(buffer); + if (buffer.size() >= 8) { + sig = BE::toUInt64(buffer.data()); + } else if (buffer.size() >= 4) { + sig = BE::toUInt32(buffer.data()); sig <<= 4; - } else if (bufferSize >= 2) { - sig = BE::toUInt16(buffer); + } else if (buffer.size() >= 2) { + sig = BE::toUInt16(buffer.data()); sig <<= 6; } else { return ContainerFormat::Unknown; @@ -127,7 +127,7 @@ ContainerFormat parseSignature(const char *buffer, int bufferSize) case Png: return ContainerFormat::Png; case YUV4Mpeg2: - if (bufferSize >= 10 && buffer[8] == 0x32 && buffer[9] == 0x20) { + if (buffer.size() >= 10 && buffer[8] == 0x32 && buffer[9] == 0x20) { return ContainerFormat::YUV4Mpeg2; } break; @@ -178,9 +178,9 @@ ContainerFormat parseSignature(const char *buffer, int bufferSize) case PhotoshopDocument: return ContainerFormat::PhotoshopDocument; case Riff: - if (bufferSize >= 16 && BE::toUInt64(buffer + 8) == Sig64::RiffAvi) { + if (buffer.size() >= 16 && BE::toUInt64(buffer.data() + 8) == Sig64::RiffAvi) { return ContainerFormat::RiffAvi; - } else if (bufferSize >= 12 && BE::toUInt32(buffer + 8) == RiffWave) { + } else if (buffer.size() >= 12 && BE::toUInt32(buffer.data() + 8) == RiffWave) { return ContainerFormat::RiffWave; } else { return ContainerFormat::Riff; @@ -248,7 +248,7 @@ ContainerFormat parseSignature(const char *buffer, int bufferSize) * \remarks The abbreviation might be used as file extension. * \returns Returns an empty string if no abbreviation is available. */ -const char *containerFormatAbbreviation(ContainerFormat containerFormat, MediaType mediaType, unsigned int version) +std::string_view containerFormatAbbreviation(ContainerFormat containerFormat, MediaType mediaType, unsigned int version) { switch (containerFormat) { case ContainerFormat::Ac3Frames: @@ -370,7 +370,7 @@ const char *containerFormatAbbreviation(ContainerFormat containerFormat, MediaTy * * Returns "unknown" if no name is available. */ -const char *containerFormatName(ContainerFormat containerFormat) +std::string_view containerFormatName(ContainerFormat containerFormat) { switch (containerFormat) { case ContainerFormat::Ac3Frames: @@ -475,7 +475,7 @@ const char *containerFormatName(ContainerFormat containerFormat) * * Returns an empty string if there is no subversion available. */ -const char *containerFormatSubversion(ContainerFormat containerFormat) +std::string_view containerFormatSubversion(ContainerFormat containerFormat) { switch (containerFormat) { case ContainerFormat::Gif87a: @@ -496,7 +496,7 @@ const char *containerFormatSubversion(ContainerFormat containerFormat) * * Returns an empty string if there is no MIME-type available. */ -const char *containerMimeType(ContainerFormat containerFormat, MediaType mediaType) +std::string_view containerMimeType(ContainerFormat containerFormat, MediaType mediaType) { switch (containerFormat) { case ContainerFormat::Ac3Frames: diff --git a/signature.h b/signature.h index 859e07e..846e247 100644 --- a/signature.h +++ b/signature.h @@ -4,6 +4,7 @@ #include "./mediaformat.h" #include +#include namespace TagParser { @@ -66,15 +67,21 @@ enum class ContainerFormat : unsigned int { Zip, /**< ZIP archive */ }; -TAG_PARSER_EXPORT ContainerFormat parseSignature(const char *buffer, int bufferSize); -TAG_PARSER_EXPORT const char *containerFormatName(ContainerFormat containerFormat); -TAG_PARSER_EXPORT const char *containerFormatAbbreviation( +TAG_PARSER_EXPORT ContainerFormat parseSignature(const char *buffer, std::size_t bufferSize); +TAG_PARSER_EXPORT ContainerFormat parseSignature(std::string_view buffer); +TAG_PARSER_EXPORT std::string_view containerFormatName(ContainerFormat containerFormat); +TAG_PARSER_EXPORT std::string_view containerFormatAbbreviation( ContainerFormat containerFormat, MediaType mediaType = MediaType::Unknown, unsigned int version = 0); -TAG_PARSER_EXPORT const char *containerFormatSubversion(ContainerFormat containerFormat); -TAG_PARSER_EXPORT const char *containerMimeType(ContainerFormat containerFormat, MediaType mediaType = MediaType::Unknown); +TAG_PARSER_EXPORT std::string_view containerFormatSubversion(ContainerFormat containerFormat); +TAG_PARSER_EXPORT std::string_view containerMimeType(ContainerFormat containerFormat, MediaType mediaType = MediaType::Unknown); TAG_PARSER_EXPORT TagTargetLevel containerTargetLevel(ContainerFormat containerFormat, std::uint64_t targetLevelValue); TAG_PARSER_EXPORT std::uint64_t containerTargetLevelValue(ContainerFormat containerFormat, TagTargetLevel targetLevel); +inline ContainerFormat parseSignature(const char *buffer, std::size_t bufferSize) +{ + return parseSignature(std::string_view(buffer, bufferSize)); +} + } // namespace TagParser #endif // TAG_PARSER_SIGNATURE_H diff --git a/size.cpp b/size.cpp index c4356b1..2c7b49c 100644 --- a/size.cpp +++ b/size.cpp @@ -6,7 +6,7 @@ namespace TagParser { * \brief Returns an abbreviation for the current instance, eg. 720p for sizes greather than 1280×720 * and 1080p for sizes greather than 1920×1080. */ -const char *Size::abbreviation() const +std::string_view Size::abbreviation() const { if (*this >= Size(7680, 4320)) { return "8k"; diff --git a/size.h b/size.h index fd37b89..c7623a2 100644 --- a/size.h +++ b/size.h @@ -7,6 +7,7 @@ #include #include +#include namespace TagParser { @@ -23,7 +24,7 @@ public: void setWidth(std::uint32_t value); void setHeight(std::uint32_t value); constexpr std::uint32_t resolution() const; - const char *abbreviation() const; + std::string_view abbreviation() const; bool constexpr isNull() const; bool constexpr operator==(const Size &other) const; diff --git a/tag.h b/tag.h index 0ed3dcb..2d3ccce 100644 --- a/tag.h +++ b/tag.h @@ -110,7 +110,7 @@ public: virtual ~Tag(); virtual TagType type() const; - virtual const char *typeName() const; + virtual std::string_view typeName() const; std::string toString() const; virtual TagTextEncoding proposedTextEncoding() const; virtual bool canEncodingBeUsed(TagTextEncoding encoding) const; @@ -126,7 +126,7 @@ public: const TagTarget &target() const; void setTarget(const TagTarget &target); virtual TagTargetLevel targetLevel() const; - const char *targetLevelName() const; + std::string_view targetLevelName() const; bool isTargetingLevel(TagTargetLevel tagTargetLevel) const; std::string targetString() const; virtual unsigned int fieldCount() const = 0; @@ -151,7 +151,7 @@ inline TagType Tag::type() const return TagType::Unspecified; } -inline const char *Tag::typeName() const +inline std::string_view Tag::typeName() const { return "unspecified"; } @@ -196,9 +196,9 @@ inline TagTargetLevel Tag::targetLevel() const return TagTargetLevel::Unspecified; } -inline const char *Tag::targetLevelName() const +inline std::string_view Tag::targetLevelName() const { - return supportsTarget() ? tagTargetLevelName(targetLevel()) : nullptr; + return supportsTarget() ? tagTargetLevelName(targetLevel()) : std::string_view(); } inline bool Tag::isTargetingLevel(TagTargetLevel tagTargetLevel) const diff --git a/tagtarget.cpp b/tagtarget.cpp index da100fb..1d6bc6c 100644 --- a/tagtarget.cpp +++ b/tagtarget.cpp @@ -14,7 +14,7 @@ namespace TagParser { /*! * \brief Returns a string representation for the specified \a tagTargetLevel. */ -const char *tagTargetLevelName(TagTargetLevel tagTargetLevel) +std::string_view tagTargetLevelName(TagTargetLevel tagTargetLevel) { switch (tagTargetLevel) { case TagTargetLevel::Shot: @@ -32,7 +32,7 @@ const char *tagTargetLevelName(TagTargetLevel tagTargetLevel) case TagTargetLevel::Collection: return "collection"; default: - return ""; + return std::string_view(); } } @@ -57,15 +57,15 @@ const char *tagTargetLevelName(TagTargetLevel tagTargetLevel) * \brief Returns the string representation of the current instance. * \remarks Uses the specified \a tagTargetLevel if no levelName() is assigned. */ -string TagTarget::toString(TagTargetLevel tagTargetLevel) const +std::string TagTarget::toString(TagTargetLevel tagTargetLevel) const { - string levelString; + auto levelString = std::string(); if (level()) { levelString += "level "; levelString += numberToString(level()); } - const char *defaultLevelName; - if (!levelName().empty() || *(defaultLevelName = tagTargetLevelName(tagTargetLevel))) { + auto defaultLevelName = std::string_view(); + if (!levelName().empty() || !(defaultLevelName = tagTargetLevelName(tagTargetLevel)).empty()) { if (!levelString.empty()) { levelString += ' '; } diff --git a/tagtarget.h b/tagtarget.h index 234474c..6fcc698 100644 --- a/tagtarget.h +++ b/tagtarget.h @@ -15,7 +15,7 @@ namespace TagParser { */ enum class TagTargetLevel : unsigned char { Unspecified, Shot, Subtrack, Track, Part, Album, Edition, Collection }; -TAG_PARSER_EXPORT const char *tagTargetLevelName(TagTargetLevel tagTargetLevel); +TAG_PARSER_EXPORT std::string_view tagTargetLevelName(TagTargetLevel tagTargetLevel); class TAG_PARSER_EXPORT TagTarget { public: diff --git a/tagvalue.cpp b/tagvalue.cpp index 6e34c6d..254c5ba 100644 --- a/tagvalue.cpp +++ b/tagvalue.cpp @@ -22,7 +22,7 @@ namespace TagParser { /*! * \brief Returns the string representation of the specified \a dataType. */ -const char *tagDataTypeString(TagDataType dataType) +std::string_view tagDataTypeString(TagDataType dataType) { switch (dataType) { case TagDataType::Text: @@ -655,7 +655,7 @@ void TagValue::toString(string &result, TagTextEncoding encoding) const const auto genreIndex = toInteger(); if (Id3Genres::isEmptyGenre(genreIndex)) { result.clear(); - } else if (const char *genreName = Id3Genres::stringFromIndex(genreIndex)) { + } else if (const auto genreName = Id3Genres::stringFromIndex(genreIndex); !genreName.empty()) { result.assign(genreName); } else { throw ConversionException("No string representation for the assigned standard genre index available."); @@ -739,7 +739,7 @@ void TagValue::toWString(std::u16string &result, TagTextEncoding encoding) const const auto genreIndex = toInteger(); if (Id3Genres::isEmptyGenre(genreIndex)) { regularStrRes.clear(); - } else if (const char *genreName = Id3Genres::stringFromIndex(genreIndex)) { + } else if (const auto genreName = Id3Genres::stringFromIndex(genreIndex); !genreName.empty()) { regularStrRes.assign(genreName); } else { throw ConversionException("No string representation for the assigned standard genre index available."); diff --git a/tagvalue.h b/tagvalue.h index 38b5cf9..d7b64ac 100644 --- a/tagvalue.h +++ b/tagvalue.h @@ -102,6 +102,8 @@ public: const char *text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified); explicit TagValue( const std::string &text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified); + explicit TagValue( + std::string_view text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified); explicit TagValue(int value); explicit TagValue( const char *data, std::size_t length, TagDataType type = TagDataType::Undefined, TagTextEncoding encoding = TagTextEncoding::Latin1); @@ -140,10 +142,11 @@ public: std::size_t dataSize() const; char *dataPointer(); const char *dataPointer() const; + std::string_view data() const; const std::string &description() const; - void setDescription(const std::string &value, TagTextEncoding encoding = TagTextEncoding::Latin1); + void setDescription(std::string_view value, TagTextEncoding encoding = TagTextEncoding::Latin1); const std::string &mimeType() const; - void setMimeType(const std::string &mimeType); + void setMimeType(std::string_view mimeType); const Locale &locale() const; Locale &locale(); void setLocale(const Locale &locale); @@ -164,6 +167,8 @@ public: TagTextEncoding convertTo = TagTextEncoding::Unspecified); void assignText( const std::string &text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified); + void assignText( + std::string_view text, TagTextEncoding textEncoding = TagTextEncoding::Latin1, TagTextEncoding convertTo = TagTextEncoding::Unspecified); void assignInteger(int value); void assignStandardGenreIndex(int index); void assignData(const char *data, std::size_t length, TagDataType type = TagDataType::Binary, TagTextEncoding encoding = TagTextEncoding::Latin1); @@ -264,6 +269,22 @@ inline TagValue::TagValue(const std::string &text, TagTextEncoding textEncoding, assignText(text, textEncoding, convertTo); } +/*! + * \brief Constructs a new TagValue holding a copy of the given \a text. + * \param text Specifies the text to be assigned. + * \param textEncoding Specifies the encoding of the given \a text. + * \param convertTo Specifies the encoding to convert \a text to; set to TagTextEncoding::Unspecified to + * use \a textEncoding without any character set conversions. + * \throws Throws a ConversionException if the conversion the specified character set fails. + * \remarks Strips the BOM of the specified \a text. + */ +inline TagValue::TagValue(std::string_view text, TagTextEncoding textEncoding, TagTextEncoding convertTo) + : m_descEncoding(TagTextEncoding::Latin1) + , m_flags(TagValueFlags::None) +{ + assignText(text, textEncoding, convertTo); +} + /*! * \brief Constructs a new TagValue holding the given integer \a value. */ @@ -387,6 +408,20 @@ inline void TagValue::assignText(const std::string &text, TagTextEncoding textEn assignText(text.data(), text.size(), textEncoding, convertTo); } +/*! + * \brief Assigns a copy of the given \a text. + * \param text Specifies the text to be assigned. + * \param textEncoding Specifies the encoding of the given \a text. + * \param convertTo Specifies the encoding to convert \a text to; set to TagTextEncoding::Unspecified to + * use \a textEncoding without any character set conversions. + * \throws Throws a ConversionException if the conversion the specified character set fails. + * \remarks Strips the BOM of the specified \a text. + */ +inline void TagValue::assignText(std::string_view text, TagTextEncoding textEncoding, TagTextEncoding convertTo) +{ + assignText(text.data(), text.size(), textEncoding, convertTo); +} + /*! * \brief Assigns the given PositionInSet \a value. */ @@ -542,6 +577,14 @@ inline const char *TagValue::dataPointer() const return m_ptr.get(); } +/*! + * \brief Returns the currently assigned raw data. + */ +inline std::string_view TagValue::data() const +{ + return std::string_view(m_ptr.get(), m_size); +} + /*! * \brief Returns the description. * \remarks @@ -568,7 +611,7 @@ inline const std::string &TagValue::description() const * - description() and descriptionEncoding() * - convertDescriptionEncoding() to change the description encoding after assignment */ -inline void TagValue::setDescription(const std::string &value, TagTextEncoding encoding) +inline void TagValue::setDescription(std::string_view value, TagTextEncoding encoding) { m_desc = value; m_descEncoding = encoding; @@ -593,7 +636,7 @@ inline const std::string &TagValue::mimeType() const * be ignored by the implementation of the tag format if not supported. * \sa mimeType() */ -inline void TagValue::setMimeType(const std::string &mimeType) +inline void TagValue::setMimeType(std::string_view mimeType) { m_mimeType = mimeType; } diff --git a/tests/overallgeneral.cpp b/tests/overallgeneral.cpp index 0ceaa16..d7b95a7 100644 --- a/tests/overallgeneral.cpp +++ b/tests/overallgeneral.cpp @@ -12,11 +12,11 @@ OverallTests::OverallTests() */ void OverallTests::setUp() { - m_testTitle.assignText("some title", TagTextEncoding::Utf8); - m_testComment.assignText("some cómment", TagTextEncoding::Utf8); - m_testComment.setDescription("some descriptión", TagTextEncoding::Utf8); - m_testCommentWithoutDescription.assignText("some cómment", TagTextEncoding::Utf8); - m_testAlbum.assignText("some album", TagTextEncoding::Utf8); + m_testTitle.assignText("some title"sv, TagTextEncoding::Utf8); + m_testComment.assignText("some cómment"sv, TagTextEncoding::Utf8); + m_testComment.setDescription("some descriptión"sv, TagTextEncoding::Utf8); + m_testCommentWithoutDescription.assignText("some cómment"sv, TagTextEncoding::Utf8); + m_testAlbum.assignText("some album"sv, TagTextEncoding::Utf8); m_testPartNumber.assignInteger(41); m_testTotalParts.assignInteger(61); m_testPosition.assignPosition(PositionInSet(41, 61)); diff --git a/vorbis/vorbiscomment.cpp b/vorbis/vorbiscomment.cpp index dc66768..c56c9aa 100644 --- a/vorbis/vorbiscomment.cpp +++ b/vorbis/vorbiscomment.cpp @@ -49,50 +49,50 @@ VorbisComment::IdentifierType VorbisComment::internallyGetFieldId(KnownField fie using namespace VorbisCommentIds; switch (field) { case KnownField::Album: - return album(); + return std::string(album()); case KnownField::Artist: - return artist(); + return std::string(artist()); case KnownField::Comment: - return comment(); + return std::string(comment()); case KnownField::Cover: - return cover(); + return std::string(cover()); case KnownField::RecordDate: case KnownField::Year: - return date(); + return std::string(date()); case KnownField::Title: - return title(); + return std::string(title()); case KnownField::Genre: - return genre(); + return std::string(genre()); case KnownField::TrackPosition: - return trackNumber(); + return std::string(trackNumber()); case KnownField::DiskPosition: - return diskNumber(); + return std::string(diskNumber()); case KnownField::PartNumber: - return partNumber(); + return std::string(partNumber()); case KnownField::Composer: - return composer(); + return std::string(composer()); case KnownField::Encoder: - return encoder(); + return std::string(encoder()); case KnownField::EncoderSettings: - return encoderSettings(); + return std::string(encoderSettings()); case KnownField::Description: - return description(); + return std::string(description()); case KnownField::Grouping: - return grouping(); + return std::string(grouping()); case KnownField::RecordLabel: - return label(); + return std::string(label()); case KnownField::Performers: - return performer(); + return std::string(performer()); case KnownField::Language: - return language(); + return std::string(language()); case KnownField::Lyricist: - return lyricist(); + return std::string(lyricist()); case KnownField::Lyrics: - return lyrics(); + return std::string(lyrics()); case KnownField::AlbumArtist: - return albumArtist(); + return std::string(albumArtist()); default: - return string(); + return std::string(); } } @@ -100,7 +100,7 @@ KnownField VorbisComment::internallyGetKnownField(const IdentifierType &id) cons { using namespace VorbisCommentIds; // clang-format off - static const map fieldMap({ + static const std::map fieldMap({ { album(), KnownField::Album }, { artist(), KnownField::Artist }, { comment(), KnownField::Comment }, @@ -185,8 +185,8 @@ template void VorbisComment::internalParse(StreamType &stream // turn "YEAR" into "DATE" (unless "DATE" exists) // note: "DATE" is an official field and "YEAR" only an inofficial one but present in some files. In consistency with // MediaInfo and VLC player it is treated like "DATE" here. - if (fields().find(VorbisCommentIds::date()) == fields().end()) { - const auto [first, end] = fields().equal_range(VorbisCommentIds::year()); + if (fields().find(std::string(VorbisCommentIds::date())) == fields().end()) { + const auto [first, end] = fields().equal_range(std::string(VorbisCommentIds::year())); for (auto i = first; i != end; ++i) { fields().insert(std::pair(VorbisCommentIds::date(), std::move(i->second))); } diff --git a/vorbis/vorbiscomment.h b/vorbis/vorbiscomment.h index 7ce6fc2..824afdb 100644 --- a/vorbis/vorbiscomment.h +++ b/vorbis/vorbiscomment.h @@ -29,7 +29,7 @@ public: VorbisComment(); static constexpr TagType tagType = TagType::VorbisComment; - static constexpr const char *tagName = "Vorbis comment"; + static constexpr std::string_view tagName = "Vorbis comment"; static constexpr TagTextEncoding defaultTextEncoding = TagTextEncoding::Utf8; bool canEncodingBeUsed(TagTextEncoding encoding) const override; diff --git a/vorbis/vorbiscommentfield.h b/vorbis/vorbiscommentfield.h index c959038..1ca84f5 100644 --- a/vorbis/vorbiscommentfield.h +++ b/vorbis/vorbiscommentfield.h @@ -58,7 +58,7 @@ public: bool isAdditionalTypeInfoUsed() const; bool supportsNestedFields() const; - static typename std::string fieldIdFromString(const char *idString, std::size_t idStringSize = std::string::npos); + static typename std::string fieldIdFromString(std::string_view idString); static std::string fieldIdToString(const std::string &id); private: @@ -85,9 +85,9 @@ inline bool VorbisCommentField::supportsNestedFields() const * \brief Converts the specified ID string representation to an actual ID. * \remarks As Vorbis field IDs are plain text the string is just passed. */ -inline std::string VorbisCommentField::fieldIdFromString(const char *idString, std::size_t idStringSize) +inline std::string VorbisCommentField::fieldIdFromString(std::string_view idString) { - return idStringSize != std::string::npos ? std::string(idString, idStringSize) : std::string(idString); + return std::string(idString); } /*! diff --git a/vorbis/vorbiscommentids.h b/vorbis/vorbiscommentids.h index ed15e92..5a1037e 100644 --- a/vorbis/vorbiscommentids.h +++ b/vorbis/vorbiscommentids.h @@ -3,6 +3,8 @@ #include "../global.h" +#include + namespace TagParser { /*! @@ -11,163 +13,163 @@ namespace TagParser { */ namespace VorbisCommentIds { -constexpr TAG_PARSER_EXPORT const char *trackNumber() +constexpr TAG_PARSER_EXPORT std::string_view trackNumber() { return "TRACKNUMBER"; } -constexpr TAG_PARSER_EXPORT const char *diskNumber() +constexpr TAG_PARSER_EXPORT std::string_view diskNumber() { return "DISCNUMBER"; } -constexpr TAG_PARSER_EXPORT const char *part() +constexpr TAG_PARSER_EXPORT std::string_view part() { return "PART"; } -constexpr TAG_PARSER_EXPORT const char *partNumber() +constexpr TAG_PARSER_EXPORT std::string_view partNumber() { return "PARTNUMBER"; } -constexpr TAG_PARSER_EXPORT const char *title() +constexpr TAG_PARSER_EXPORT std::string_view title() { return "TITLE"; } -constexpr TAG_PARSER_EXPORT const char *version() +constexpr TAG_PARSER_EXPORT std::string_view version() { return "VERSION"; } -constexpr TAG_PARSER_EXPORT const char *artist() +constexpr TAG_PARSER_EXPORT std::string_view artist() { return "ARTIST"; } -constexpr TAG_PARSER_EXPORT const char *albumArtist() +constexpr TAG_PARSER_EXPORT std::string_view albumArtist() { return "ALBUMARTIST"; } -constexpr TAG_PARSER_EXPORT const char *grouping() +constexpr TAG_PARSER_EXPORT std::string_view grouping() { return "GROUPING"; } -constexpr TAG_PARSER_EXPORT const char *album() +constexpr TAG_PARSER_EXPORT std::string_view album() { return "ALBUM"; } -constexpr TAG_PARSER_EXPORT const char *label() +constexpr TAG_PARSER_EXPORT std::string_view label() { return "LABEL"; } -constexpr TAG_PARSER_EXPORT const char *labelNo() +constexpr TAG_PARSER_EXPORT std::string_view labelNo() { return "LABELNO"; } -constexpr TAG_PARSER_EXPORT const char *language() +constexpr TAG_PARSER_EXPORT std::string_view language() { return "LANGUAGE"; } -constexpr TAG_PARSER_EXPORT const char *performer() +constexpr TAG_PARSER_EXPORT std::string_view performer() { return "PERFORMER"; } -constexpr TAG_PARSER_EXPORT const char *composer() +constexpr TAG_PARSER_EXPORT std::string_view composer() { return "COMPOSER"; } -constexpr TAG_PARSER_EXPORT const char *ensemble() +constexpr TAG_PARSER_EXPORT std::string_view ensemble() { return "ENSEMBLE"; } -constexpr TAG_PARSER_EXPORT const char *arranger() +constexpr TAG_PARSER_EXPORT std::string_view arranger() { return "ARRANGER"; } -constexpr TAG_PARSER_EXPORT const char *lyricist() +constexpr TAG_PARSER_EXPORT std::string_view lyricist() { return "LYRICIST"; } -constexpr TAG_PARSER_EXPORT const char *lyrics() +constexpr TAG_PARSER_EXPORT std::string_view lyrics() { return "LYRICS"; } -constexpr TAG_PARSER_EXPORT const char *author() +constexpr TAG_PARSER_EXPORT std::string_view author() { return "AUTHOR"; } -constexpr TAG_PARSER_EXPORT const char *conductor() +constexpr TAG_PARSER_EXPORT std::string_view conductor() { return "CONDUCTOR"; } -constexpr TAG_PARSER_EXPORT const char *encoder() +constexpr TAG_PARSER_EXPORT std::string_view encoder() { return "ENCODER"; } -constexpr TAG_PARSER_EXPORT const char *encoderSettings() +constexpr TAG_PARSER_EXPORT std::string_view encoderSettings() { return "ENCODER_OPTIONS"; } -constexpr TAG_PARSER_EXPORT const char *publisher() +constexpr TAG_PARSER_EXPORT std::string_view publisher() { return "PUBLISHER"; } -constexpr TAG_PARSER_EXPORT const char *genre() +constexpr TAG_PARSER_EXPORT std::string_view genre() { return "GENRE"; } -constexpr TAG_PARSER_EXPORT const char *originalMediaType() +constexpr TAG_PARSER_EXPORT std::string_view originalMediaType() { return "ORIGINAL_TAG_PARSER_TYPE"; } -constexpr TAG_PARSER_EXPORT const char *contentType() +constexpr TAG_PARSER_EXPORT std::string_view contentType() { return "CONTENT_TYPE"; } -constexpr TAG_PARSER_EXPORT const char *subject() +constexpr TAG_PARSER_EXPORT std::string_view subject() { return "SUBJECT"; } -constexpr TAG_PARSER_EXPORT const char *description() +constexpr TAG_PARSER_EXPORT std::string_view description() { return "DESCRIPTION"; } -constexpr TAG_PARSER_EXPORT const char *isrc() +constexpr TAG_PARSER_EXPORT std::string_view isrc() { return "ISRC"; } -constexpr TAG_PARSER_EXPORT const char *eanupn() +constexpr TAG_PARSER_EXPORT std::string_view eanupn() { return "EAN/UPN"; } -constexpr TAG_PARSER_EXPORT const char *comment() +constexpr TAG_PARSER_EXPORT std::string_view comment() { return "COMMENT"; } -constexpr TAG_PARSER_EXPORT const char *date() +constexpr TAG_PARSER_EXPORT std::string_view date() { return "DATE"; } -constexpr TAG_PARSER_EXPORT const char *year() +constexpr TAG_PARSER_EXPORT std::string_view year() { return "YEAR"; // not mentioned in https://xiph.org/vorbis/doc/v-comment.html but seen in the wild } -constexpr TAG_PARSER_EXPORT const char *location() +constexpr TAG_PARSER_EXPORT std::string_view location() { return "LOCATION"; } -constexpr TAG_PARSER_EXPORT const char *license() +constexpr TAG_PARSER_EXPORT std::string_view license() { return "LICENSE"; } -constexpr TAG_PARSER_EXPORT const char *copyright() +constexpr TAG_PARSER_EXPORT std::string_view copyright() { return "COPYRIGHT"; } -constexpr TAG_PARSER_EXPORT const char *opus() +constexpr TAG_PARSER_EXPORT std::string_view opus() { return "OPUS"; } -constexpr TAG_PARSER_EXPORT const char *sourceMedia() +constexpr TAG_PARSER_EXPORT std::string_view sourceMedia() { return "SOURCEMEDIA"; } -constexpr TAG_PARSER_EXPORT const char *cover() +constexpr TAG_PARSER_EXPORT std::string_view cover() { return "METADATA_BLOCK_PICTURE"; }