Refactor formatting list of values

This commit is contained in:
Martchus 2018-07-01 22:11:34 +02:00
parent 943123afa1
commit d64084ec78
5 changed files with 52 additions and 15 deletions

View File

@ -61,4 +61,28 @@ DiagLevel Diagnostics::level() const
return level; return level;
} }
/*!
* \brief Concatenates the specified string \a values to a list.
*/
string DiagMessage::formatList(const std::vector<string> &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 } // namespace TagParser

View File

@ -52,6 +52,8 @@ public:
const ChronoUtilities::DateTime &creationTime() const; const ChronoUtilities::DateTime &creationTime() const;
bool operator==(const DiagMessage &other) const; bool operator==(const DiagMessage &other) const;
static std::string formatList(const std::vector<std::string> &values);
private: private:
DiagLevel m_level; DiagLevel m_level;
std::string m_message; std::string m_message;

View File

@ -340,20 +340,7 @@ void Id3v2Frame::parse(BinaryReader &reader, uint32 version, uint32 maximalSize,
if (additionalValues.size() == 1) { if (additionalValues.size() == 1) {
return argsToString("value \"", additionalValues.front().toString(TagTextEncoding::Utf8), "\" is ignored."); return argsToString("value \"", additionalValues.front().toString(TagTextEncoding::Utf8), "\" is ignored.");
} }
string valuesString = "values"; return argsToString("values ", DiagMessage::formatList(TagValue::toStrings(additionalValues)), " are ignored.");
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;
}(); }();
// emplace diag message // emplace diag message

View File

@ -6,6 +6,7 @@
#include <c++utilities/chrono/datetime.h> #include <c++utilities/chrono/datetime.h>
#include <c++utilities/chrono/timespan.h> #include <c++utilities/chrono/timespan.h>
#include <c++utilities/conversion/binaryconversion.h> #include <c++utilities/conversion/binaryconversion.h>
#include <c++utilities/misc/traits.h>
#include <cstring> #include <cstring>
#include <iosfwd> #include <iosfwd>
@ -132,6 +133,11 @@ public:
static void stripBom(const char *&text, std::size_t &length, TagTextEncoding encoding); static void stripBom(const char *&text, std::size_t &length, TagTextEncoding encoding);
static void ensureHostByteOrder(std::u16string &u16str, TagTextEncoding currentEncoding); static void ensureHostByteOrder(std::u16string &u16str, TagTextEncoding currentEncoding);
template <typename ContainerType,
Traits::EnableIf<Traits::IsIteratable<ContainerType>,
std::is_same<typename std::add_const<typename std::remove_pointer<typename ContainerType::value_type>::type>::type, const TagValue>>
* = nullptr>
static std::vector<std::string> toStrings(const ContainerType &values, TagTextEncoding encoding = TagTextEncoding::Utf8);
private: private:
std::unique_ptr<char[]> m_ptr; std::unique_ptr<char[]> m_ptr;
@ -547,6 +553,24 @@ inline TagTextEncoding TagValue::descriptionEncoding() const
return m_descEncoding; return m_descEncoding;
} }
/*!
* \brief Converts the specified \a values to string using the specified \a encoding.
* \throws Throws ConversionException on failure.
* \sa toString()
*/
template <typename ContainerType,
Traits::EnableIf<Traits::IsIteratable<ContainerType>,
std::is_same<typename std::add_const<typename std::remove_pointer<typename ContainerType::value_type>::type>::type, const TagValue>> *>
std::vector<std::string> TagValue::toStrings(const ContainerType &values, TagTextEncoding encoding)
{
std::vector<std::string> res;
res.reserve(values.size());
for (const auto &value : values) {
res.emplace_back(Traits::dereferenceMaybe(value).toString(encoding));
}
return res;
}
} // namespace TagParser } // namespace TagParser
#endif // TAG_PARSER_TAGVALUE_H #endif // TAG_PARSER_TAGVALUE_H

View File

@ -129,7 +129,7 @@ void OverallTests::checkMp3Testfile2()
CPPUNIT_ASSERT_EQUAL(DiagLevel::Warning, m_diag[1].level()); CPPUNIT_ASSERT_EQUAL(DiagLevel::Warning, m_diag[1].level());
CPPUNIT_ASSERT_EQUAL("parsing TCON frame"s, m_diag[1].context()); CPPUNIT_ASSERT_EQUAL("parsing TCON frame"s, m_diag[1].context());
CPPUNIT_ASSERT_EQUAL( 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()); m_diag[1].message());
break; break;
case TagStatus::TestMetaDataPresent: case TagStatus::TestMetaDataPresent: