diff --git a/diagnostics.cpp b/diagnostics.cpp index 1faab1c..b168178 100644 --- a/diagnostics.cpp +++ b/diagnostics.cpp @@ -61,4 +61,28 @@ DiagLevel Diagnostics::level() const return level; } +/*! + * \brief Concatenates the specified string \a values to a list. + */ +string DiagMessage::formatList(const std::vector &values) +{ + auto size = values.size() * 4; + for (const auto &str : values) { + size += str.size(); + } + std::string res; + res.reserve(size); + for (auto value = values.cbegin(), end = values.cend(), last = values.cend() - 1; value != end; ++value) { + if (value == last) { + res += " and "; + } else if (!res.empty()) { + res += ", "; + } + res += '\"'; + res += *value; + res += '\"'; + } + return res; +} + } // namespace TagParser diff --git a/diagnostics.h b/diagnostics.h index a003bca..b34f4a4 100644 --- a/diagnostics.h +++ b/diagnostics.h @@ -52,6 +52,8 @@ public: const ChronoUtilities::DateTime &creationTime() const; bool operator==(const DiagMessage &other) const; + static std::string formatList(const std::vector &values); + private: DiagLevel m_level; std::string m_message; diff --git a/id3/id3v2frame.cpp b/id3/id3v2frame.cpp index e002e9c..a662c6a 100644 --- a/id3/id3v2frame.cpp +++ b/id3/id3v2frame.cpp @@ -340,20 +340,7 @@ void Id3v2Frame::parse(BinaryReader &reader, uint32 version, uint32 maximalSize, if (additionalValues.size() == 1) { return argsToString("value \"", additionalValues.front().toString(TagTextEncoding::Utf8), "\" is ignored."); } - string valuesString = "values"; - for (auto value = additionalValues.cbegin(), end = additionalValues.cend() - 1; value != end; ++value) { - valuesString += ' '; - valuesString += '\"'; - valuesString += value->toString(TagTextEncoding::Utf8); - valuesString += '\"'; - if (value != end) { - valuesString += ','; - } - } - valuesString += " and \""; - valuesString += additionalValues.back().toString(TagTextEncoding::Utf8); - valuesString += "\" are ignored."; - return valuesString; + return argsToString("values ", DiagMessage::formatList(TagValue::toStrings(additionalValues)), " are ignored."); }(); // emplace diag message diff --git a/tagvalue.h b/tagvalue.h index 30e4b9f..ed5306d 100644 --- a/tagvalue.h +++ b/tagvalue.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -132,6 +133,11 @@ public: static void stripBom(const char *&text, std::size_t &length, TagTextEncoding encoding); static void ensureHostByteOrder(std::u16string &u16str, TagTextEncoding currentEncoding); + template , + std::is_same::type>::type, const TagValue>> + * = nullptr> + static std::vector toStrings(const ContainerType &values, TagTextEncoding encoding = TagTextEncoding::Utf8); private: std::unique_ptr m_ptr; @@ -547,6 +553,24 @@ inline TagTextEncoding TagValue::descriptionEncoding() const return m_descEncoding; } +/*! + * \brief Converts the specified \a values to string using the specified \a encoding. + * \throws Throws ConversionException on failure. + * \sa toString() + */ +template , + std::is_same::type>::type, const TagValue>> *> +std::vector TagValue::toStrings(const ContainerType &values, TagTextEncoding encoding) +{ + std::vector res; + res.reserve(values.size()); + for (const auto &value : values) { + res.emplace_back(Traits::dereferenceMaybe(value).toString(encoding)); + } + return res; +} + } // namespace TagParser #endif // TAG_PARSER_TAGVALUE_H diff --git a/tests/overallmp3.cpp b/tests/overallmp3.cpp index 35c7162..c5fa079 100644 --- a/tests/overallmp3.cpp +++ b/tests/overallmp3.cpp @@ -129,7 +129,7 @@ void OverallTests::checkMp3Testfile2() CPPUNIT_ASSERT_EQUAL(DiagLevel::Warning, m_diag[1].level()); CPPUNIT_ASSERT_EQUAL("parsing TCON frame"s, m_diag[1].context()); CPPUNIT_ASSERT_EQUAL( - "Multiple strings found. This is not supported so far. Hence the additional values \"Test\", \"Example\", and \"Hard Dance\" are ignored."s, + "Multiple strings found. This is not supported so far. Hence the additional values \"Test\", \"Example\" and \"Hard Dance\" are ignored."s, m_diag[1].message()); break; case TagStatus::TestMetaDataPresent: