3#include "../id3/id3genres.h"
4#include "../tagvalue.h"
6#include <c++utilities/chrono/format.h>
7#include <c++utilities/conversion/conversionexception.h>
11#include <cppunit/TestFixture.h>
12#include <cppunit/extensions/HelperMacros.h>
17using namespace CPPUNIT_NS;
36 CPPUNIT_TEST_SUITE_END();
39 void setUp()
override;
69 CPPUNIT_ASSERT_EQUAL(TagDataType::Undefined,
TagValue().type());
74 const TagValue binary(
"123", 3, TagDataType::Binary);
75 CPPUNIT_ASSERT_EQUAL(TagDataType::Binary, binary.
type());
77 CPPUNIT_ASSERT_THROW(binary.
toString(), ConversionException);
78 CPPUNIT_ASSERT_THROW(binary.
toInteger(), ConversionException);
87 CPPUNIT_ASSERT(!integer.isEmpty());
88 CPPUNIT_ASSERT_EQUAL(TagDataType::Integer, integer.type());
89 CPPUNIT_ASSERT_EQUAL(
static_cast<std::int32_t
>(42), integer.toInteger());
90 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint64_t
>(42), integer.toUnsignedInteger());
91 CPPUNIT_ASSERT_EQUAL(
"42"s, integer.toString());
92 integer.assignInteger(2);
100 integer.assignInteger(-25);
101 CPPUNIT_ASSERT_EQUAL(
"-25"s, integer.toString());
102 CPPUNIT_ASSERT_EQUAL(
PositionInSet(-25), integer.toPositionInSet());
103 CPPUNIT_ASSERT_THROW(integer.toStandardGenreIndex(), ConversionException);
106 integer.assignInteger(0);
107 CPPUNIT_ASSERT_MESSAGE(
"explicitly assigned zero not considered empty", !integer.isEmpty());
108 CPPUNIT_ASSERT_EQUAL(
"0"s, integer.toString());
109 CPPUNIT_ASSERT_EQUAL(
DateTime(), integer.toDateTime());
110 CPPUNIT_ASSERT_EQUAL(
TimeSpan(), integer.toTimeSpan());
114 CPPUNIT_ASSERT_MESSAGE(
"cleared vale considered empty", integer.isEmpty());
115 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"only date (but not type) cleared"s, TagDataType::Integer, integer.type());
116 CPPUNIT_ASSERT_EQUAL(
static_cast<std::int32_t
>(0), integer.toInteger());
117 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint64_t
>(0), integer.toUnsignedInteger());
118 CPPUNIT_ASSERT_EQUAL(
string(), integer.toString());
119 CPPUNIT_ASSERT_EQUAL(
DateTime(), integer.toDateTime());
120 CPPUNIT_ASSERT_EQUAL(
TimeSpan(), integer.toTimeSpan());
125 auto unsignedInteger =
TagValue(
static_cast<std::uint64_t
>(42ul));
126 CPPUNIT_ASSERT(!unsignedInteger.isEmpty());
127 CPPUNIT_ASSERT_EQUAL(TagDataType::UnsignedInteger, unsignedInteger.type());
128 CPPUNIT_ASSERT_EQUAL(
static_cast<std::int32_t
>(42), unsignedInteger.toInteger());
129 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint64_t
>(42), unsignedInteger.toUnsignedInteger());
130 CPPUNIT_ASSERT_EQUAL(
"42"s, unsignedInteger.toString());
131 unsignedInteger.assignUnsignedInteger(2);
135 unsignedInteger.clearData();
139 unsignedInteger.assignInteger(0);
140 CPPUNIT_ASSERT_MESSAGE(
"explicitly assigned zero not considered empty", !unsignedInteger.isEmpty());
141 CPPUNIT_ASSERT_EQUAL(
"0"s, unsignedInteger.toString());
142 CPPUNIT_ASSERT_EQUAL(
DateTime(), unsignedInteger.toDateTime());
143 CPPUNIT_ASSERT_EQUAL(
TimeSpan(), unsignedInteger.toTimeSpan());
150 CPPUNIT_ASSERT_EQUAL(4, test.
toInteger());
152 CPPUNIT_ASSERT_EQUAL(
"4/23"s, test.
toString());
154 CPPUNIT_ASSERT_THROW(test.
toDateTime(), ConversionException);
155 CPPUNIT_ASSERT_THROW(test.
toTimeSpan(), ConversionException);
160 const TimeSpan fiveMinutes(TimeSpan::fromMinutes(5));
163 CPPUNIT_ASSERT_EQUAL(timeSpan,
TagValue(timeSpan));
164 CPPUNIT_ASSERT_EQUAL(fiveMinutes, timeSpan.
toTimeSpan());
165 CPPUNIT_ASSERT_EQUAL(fiveMinutes.toString(), timeSpan.
toString());
166 CPPUNIT_ASSERT_THROW(timeSpan.
toInteger(), ConversionException);
167 CPPUNIT_ASSERT_THROW(timeSpan.
toDateTime(), ConversionException);
173 const auto now = DateTime::now();
175 value.assignDateTime(now);
176 CPPUNIT_ASSERT_EQUAL(value,
TagValue(value));
177 CPPUNIT_ASSERT_EQUAL(now, value.toDateTime());
178 CPPUNIT_ASSERT_EQUAL(now.toIsoString(), value.toString());
179 CPPUNIT_ASSERT_THROW(value.toInteger(), ConversionException);
180 CPPUNIT_ASSERT_THROW(value.toTimeSpan(), ConversionException);
181 CPPUNIT_ASSERT_THROW(value.toPositionInSet(), ConversionException);
186 auto expr = DateTimeExpression::fromIsoString(
"2007");
188 value.assignDateTimeExpression(expr);
189 CPPUNIT_ASSERT_EQUAL(value,
TagValue(expr));
190 CPPUNIT_ASSERT_EQUAL(expr.value, value.toDateTime());
191 CPPUNIT_ASSERT_EQUAL(expr, value.toDateTimeExpression());
192 CPPUNIT_ASSERT_EQUAL(expr.toIsoString(), value.toString());
193 CPPUNIT_ASSERT_THROW(value.toInteger(), ConversionException);
194 CPPUNIT_ASSERT_THROW(value.toTimeSpan(), ConversionException);
195 CPPUNIT_ASSERT_THROW(value.toPositionInSet(), ConversionException);
200 const auto tagValue =
TagValue(
Popularity{ .
user =
"foo", .rating = 40.0, .playCounter = 123, .scale = TagType::VorbisComment });
202 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to popularity (user)",
"foo"s, popularity.user);
203 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to popularity (rating)", 40.0, popularity.rating);
204 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to popularity (play counter)", std::uint64_t(123), popularity.playCounter);
205 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to popularity (scale)", TagType::VorbisComment, popularity.scale);
206 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to string",
"foo|40|123"s, tagValue.toString());
207 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to string (only rating)",
"43"s,
TagValue(
Popularity{ .
rating = 43 }).toString());
208 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to integer", 40, tagValue.toInteger());
209 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to unsigned integer",
static_cast<std::uint64_t
>(40), tagValue.toUnsignedInteger());
210 CPPUNIT_ASSERT_THROW_MESSAGE(
211 "failing conversion to other type",
TagValue(
"foo|bar"sv, TagTextEncoding::Latin1).toPopularity(), ConversionException);
212 const auto scaledPopularity = tagValue.toScaledPopularity();
213 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"rating scaled to generic scale", 2.0, scaledPopularity.rating);
214 CPPUNIT_ASSERT_THROW_MESSAGE(
215 "failed to scale if no scaling for specified format defined", tagValue.toScaledPopularity(TagType::Mp4Tag), ConversionException);
220 CPPUNIT_ASSERT_EQUAL(
"15\xe4"s,
TagValue(
"15ä", 4, TagTextEncoding::Utf8).toString(TagTextEncoding::Latin1));
221 CPPUNIT_ASSERT_EQUAL(
"15\xe4"s,
TagValue(
"15ä", TagTextEncoding::Utf8, TagTextEncoding::Latin1).toString());
222 CPPUNIT_ASSERT_EQUAL(
"15ä"s,
TagValue(
"15ä", 4, TagTextEncoding::Utf8).toString(TagTextEncoding::Utf8));
223 CPPUNIT_ASSERT_EQUAL(
"\x31\0\x35\0"s,
TagValue(15).toString(TagTextEncoding::Utf16LittleEndian));
224 CPPUNIT_ASSERT_EQUAL(
"\0\x31\0\x35"s,
TagValue(15).toString(TagTextEncoding::Utf16BigEndian));
225 CPPUNIT_ASSERT_EQUAL(15,
TagValue(
"\0\x31\0\x35"s, TagTextEncoding::Utf16BigEndian).toInteger());
226 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint64_t
>(15),
TagValue(
"\0\x31\0\x35"s, TagTextEncoding::Utf16BigEndian).toUnsignedInteger());
227 CPPUNIT_ASSERT_EQUAL_MESSAGE(
228 "original encoding preserved",
"15ä"s,
TagValue(
"15ä", 4, TagTextEncoding::Utf8).toString(TagTextEncoding::Unspecified));
229 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"original encoding preserved",
"\0\x31\0\x35"s,
230 TagValue(
"\0\x31\0\x35", 4, TagTextEncoding::Utf16BigEndian).toString(TagTextEncoding::Unspecified));
231 CPPUNIT_ASSERT_EQUAL_MESSAGE(
232 "UTF-8 BOM truncated",
"täst"s,
TagValue(
"\xef\xbb\xbftäst", 8, TagTextEncoding::Utf8).toString(TagTextEncoding::Unspecified));
233 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"UTF-16 LE BOM truncated",
"\0t\0\xe4\0s\0t"s,
234 TagValue(
"\xff\xfe\0t\0\xe4\0s\0t", 10, TagTextEncoding::Utf16LittleEndian).toString(TagTextEncoding::Unspecified));
235 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"UTF-16 BE BOM truncated",
"t\0\xe4\0s\0t\0"s,
236 TagValue(
"\xfe\xfft\0\xe4\0s\0t\0", 10, TagTextEncoding::Utf16BigEndian).toString(TagTextEncoding::Unspecified));
237 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion via c'tor",
"15\xe4"s,
238 TagValue(
"\xef\xbb\xbf\x31\x35ä", 7, TagTextEncoding::Utf8, TagTextEncoding::Latin1).toString(TagTextEncoding::Unspecified));
239 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to int", -15,
TagValue(
" - 156", 5, TagTextEncoding::Utf8).toInteger());
240 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to int", 15,
TagValue(
"\0\x31\0\x35", 4, TagTextEncoding::Utf16BigEndian).toInteger());
241 CPPUNIT_ASSERT_THROW_MESSAGE(
"failing conversion to int",
TagValue(
"15ä", 4, TagTextEncoding::Utf8).toInteger(), ConversionException);
242 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to pos",
PositionInSet(4, 15),
TagValue(
"4 / 15", 6, TagTextEncoding::Utf8).toPositionInSet());
243 CPPUNIT_ASSERT_EQUAL_MESSAGE(
244 "conversion to pos",
PositionInSet(15),
TagValue(
"\0\x31\0\x35", 4, TagTextEncoding::Utf16BigEndian).toPositionInSet());
245 CPPUNIT_ASSERT_THROW_MESSAGE(
"failing conversion pos",
TagValue(
"a4 / 15", 7, TagTextEncoding::Utf8).toPositionInSet(), ConversionException);
246 CPPUNIT_ASSERT_EQUAL_MESSAGE(
247 "conversion to date time", DateTime::fromDate(2004, 4, 15),
TagValue(
"2004-04-15", 10, TagTextEncoding::Utf8).toDateTime());
248 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to date time expression", DateTimeExpression::fromIsoString(
"2004-04"),
249 TagValue(
"2004-04-15", 7, TagTextEncoding::Utf8).toDateTimeExpression());
250 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to date from UTF-16", DateTime::fromDate(2015, 4, 15),
251 TagValue(
"\0\x32\0\x30\0\x31\0\x35\0\x2d\0\x30\0\x34\0\x2d\0\x31\0\x35", 20, TagTextEncoding::Utf16BigEndian).toDateTime());
252 CPPUNIT_ASSERT_THROW_MESSAGE(
"failing conversion to date",
TagValue(
"_", 1, TagTextEncoding::Utf8).toDateTime(), ConversionException);
253 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to time span", TimeSpan::fromHours(1.5),
TagValue(
"01:30:00", 10, TagTextEncoding::Utf8).toTimeSpan());
254 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to time span from UTF-16", TimeSpan::fromHours(1.5),
255 TagValue(
"\0\x31\0\x3a\0\x33\0\x30\0\x3a\0\x30\0\x30", 14, TagTextEncoding::Utf16BigEndian).toTimeSpan());
256 CPPUNIT_ASSERT_THROW_MESSAGE(
"failing conversion to time span",
TagValue(
"_", 1, TagTextEncoding::Utf8).toTimeSpan(), ConversionException);
257 CPPUNIT_ASSERT_EQUAL_MESSAGE(
258 "conversion to genre from index", 15,
TagValue(
"\0\x31\0\x35", 4, TagTextEncoding::Utf16BigEndian).toStandardGenreIndex());
259 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to genre from name", 2,
TagValue(
"Country", 7, TagTextEncoding::Latin1).toStandardGenreIndex());
260 CPPUNIT_ASSERT_THROW_MESSAGE(
261 "failing conversion to genre",
TagValue(
"Kountry", 7, TagTextEncoding::Latin1).toStandardGenreIndex(), ConversionException);
263 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to popularity (user)",
"foo"s, popularity.user);
264 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to popularity (rating)", 42.0, popularity.rating);
265 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"conversion to popularity (play counter)", std::uint64_t(123), popularity.playCounter);
266 CPPUNIT_ASSERT_THROW_MESSAGE(
"failing conversion to popularity",
TagValue(
"foo|bar"sv).toPopularity(), ConversionException);
271 CPPUNIT_ASSERT_MESSAGE(
"equality requires identical types or identical string representation"s,
TagValue(0) !=
TagValue::empty());
272 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"comparison of equal types"s,
TagValue(15),
TagValue(15));
273 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"types might differ"s,
TagValue(
"15", 2, TagTextEncoding::Latin1),
TagValue(15));
275 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"comparison of equal UTF-16 strings"s,
TagValue(
"\x31\0\x32\0", 4, TagTextEncoding::Utf16LittleEndian),
276 TagValue(
"\x31\0\x32\0", 4, TagTextEncoding::Utf16LittleEndian));
277 CPPUNIT_ASSERT_MESSAGE(
"comparison of different UTF-16 strings"s,
278 TagValue(
"\x31\0\x33\0", 4, TagTextEncoding::Utf16LittleEndian) !=
TagValue(
"\x31\0\x32\0", 4, TagTextEncoding::Utf16LittleEndian));
279 CPPUNIT_ASSERT_EQUAL_MESSAGE(
280 "comparison of equal binary data"s,
TagValue(
"\x31\0\x32\0", 4, TagDataType::Binary),
TagValue(
"\x31\0\x32\0", 4, TagDataType::Binary));
281 CPPUNIT_ASSERT_MESSAGE(
282 "comparison of different binary data"s,
TagValue(
"\x31\0\x33\0", 4, TagDataType::Binary) !=
TagValue(
"\x31\0\x32\0", 4, TagDataType::Binary));
283 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"different encodings are converted if neccassary"s,
TagValue(
"\0\x31\0\x35", 4, TagTextEncoding::Utf16BigEndian),
284 TagValue(
"15", 2, TagTextEncoding::Latin1));
285 CPPUNIT_ASSERT_EQUAL_MESSAGE(
286 "encoding is ignored when not relevant for types"s,
TagValue(
"\0\x31\0\x35", 4, TagTextEncoding::Utf16BigEndian),
TagValue(15));
287 const TagValue fooTagValue(
"foo", 3, TagDataType::Text), fOoTagValue(
"fOo", 3, TagDataType::Text);
288 CPPUNIT_ASSERT_MESSAGE(
"string comparison case-sensitive by default"s, fooTagValue != fOoTagValue);
289 CPPUNIT_ASSERT_MESSAGE(
"case-insensitive string comparison"s, fooTagValue.compareTo(fOoTagValue, TagValueComparisionFlags::CaseInsensitive));
290 const auto popularity =
Popularity{ .
user =
"some user", .rating = 200, .playCounter = 0 };
292 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"comparison of equal popularity (string and binary representation)"s,
TagValue(
"some user|200.0"sv), first);
293 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"comparison of equal popularity (only binary representation)"s, first, second);
295 CPPUNIT_ASSERT_MESSAGE(
"popularity not equal"s, first !=
TagValue(
Popularity({ .rating = 200 })));
300 CPPUNIT_ASSERT_MESSAGE(
"meta-data must be equal"s, withDescription !=
TagValue(15));
301 CPPUNIT_ASSERT_MESSAGE(
"different meta-data ignored"s, withDescription.
compareTo(
TagValue(15), TagValueComparisionFlags::IgnoreMetaData));
302 TagValue withDescription2(withDescription);
303 CPPUNIT_ASSERT_EQUAL(withDescription, withDescription2);
305 CPPUNIT_ASSERT(withDescription != withDescription2);
307 CPPUNIT_ASSERT_EQUAL(withDescription, withDescription2);
309 CPPUNIT_ASSERT_MESSAGE(
"meta-data case must match by default"s, withDescription != withDescription2);
310 CPPUNIT_ASSERT_MESSAGE(
"meta-data case ignored"s, withDescription.
compareTo(withDescription2, TagValueComparisionFlags::CaseInsensitive));
315 const auto genericZero =
Popularity{ .
rating = 0.0, .scale = TagType::Unspecified };
316 const auto genericMin =
Popularity{ .
rating = 1.0, .scale = TagType::Unspecified };
317 const auto genericMax =
Popularity{ .
rating = 5.0, .scale = TagType::Unspecified };
318 const auto genericMiddle =
Popularity{ .
rating = 3.0, .scale = TagType::Unspecified };
319 const auto id3zero =
Popularity{ .
rating = 0.0, .scale = TagType::Id3v2Tag };
320 const auto id3min =
Popularity{ .
rating = 1.0, .scale = TagType::Id3v2Tag };
321 const auto id3max =
Popularity{ .
rating = 255.0, .scale = TagType::Id3v2Tag };
322 const auto id3middle =
Popularity{ .
rating = 128.0, .scale = TagType::Id3v2Tag };
323 const auto vorbisZero =
Popularity{ .
rating = 0.0, .scale = TagType::VorbisComment };
324 const auto vorbisMin =
Popularity{ .
rating = 20.0, .scale = TagType::VorbisComment };
325 const auto vorbisMax =
Popularity{ .
rating = 100.0, .scale = TagType::OggVorbisComment };
326 const auto vorbisMiddle =
Popularity{ .
rating = 60.0, .scale = TagType::OggVorbisComment };
327 const auto mkvMin =
Popularity{ .
rating = 0.0, .scale = TagType::MatroskaTag };
328 const auto mkvMax =
Popularity{ .
rating = 5.0, .scale = TagType::MatroskaTag };
329 const auto mkvMiddle =
Popularity{ .
rating = 2.5, .scale = TagType::MatroskaTag };
330 for (
const auto &rawZero : { id3zero, vorbisZero }) {
331 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"zero: raw to generic", genericZero.rating, rawZero.scaled(TagType::Unspecified).rating);
332 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"zero: generic to raw ", rawZero.rating, genericZero.scaled(rawZero.scale).rating);
334 for (
const auto &rawMin : { id3min, vorbisMin, mkvMin }) {
335 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"min: raw to generic", genericMin.rating, rawMin.scaled(TagType::Unspecified).rating);
336 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"min: generic to raw ", rawMin.rating, genericMin.scaled(rawMin.scale).rating);
338 for (
const auto &rawMax : { id3max, vorbisMax, mkvMax }) {
339 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"max: raw to generic", genericMax.rating, rawMax.scaled(TagType::Unspecified).rating);
340 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"max: generic to raw ", rawMax.rating, genericMax.scaled(rawMax.scale).rating);
342 for (
const auto &rawMiddle : { id3middle, vorbisMiddle, mkvMiddle }) {
343 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"middle: raw to generic", genericMiddle.rating, rawMiddle.scaled(TagType::Unspecified).rating);
344 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"middle: generic to raw ", rawMiddle.rating, genericMiddle.scaled(rawMiddle.scale).rating);
static constexpr int emptyGenreIndex()
Returns the preferred genre index to indicate that no genre is set at all.
static std::string_view stringFromIndex(int index)
Returns the genre name for the specified numerical denotation as C-style string.
The PositionInSet class describes the position of an element in a set which consists of a certain num...
The TagValue class wraps values of different types.
void setMimeType(std::string_view mimeType)
Sets the MIME type.
const std::string & mimeType() const
Returns the MIME type.
bool compareTo(const TagValue &other, TagValueComparisionFlags options=TagValueComparisionFlags::None) const
Returns whether both instances are equal.
CppUtilities::DateTime toDateTime() const
Converts the value of the current TagValue object to its equivalent DateTime representation (using th...
void setDescription(std::string_view value, TagTextEncoding encoding=TagTextEncoding::Latin1)
Sets the description.
std::uint64_t toUnsignedInteger() const
std::int32_t toInteger() const
Converts the value of the current TagValue object to its equivalent integer representation.
PositionInSet toPositionInSet() const
Converts the value of the current TagValue object to its equivalent PositionInSet representation.
TagDataType type() const
Returns the type of the assigned value.
void assignTimeSpan(CppUtilities::TimeSpan value)
Assigns the given TimeSpan value.
Popularity toPopularity() const
Converts the value of the current TagValue object to its equivalent Popularity representation.
std::size_t dataSize() const
Returns the size of the assigned value in bytes.
std::string toString(TagTextEncoding encoding=TagTextEncoding::Unspecified) const
Converts the value of the current TagValue object to its equivalent std::string representation.
static const TagValue & empty()
Returns a default-constructed TagValue where TagValue::isNull() and TagValue::isEmpty() both return t...
int toStandardGenreIndex() const
Converts the value of the current TagValue object to its equivalent standard genre index.
CppUtilities::TimeSpan toTimeSpan() const
Converts the value of the current TagValue object to its equivalent TimeSpan representation.
char * dataPointer()
Returns a pointer to the raw data assigned to the current instance.
The TagValueTests class tests the TagParser::TagValue class.
void testDateTimeExpression()
void testUnsignedInteger()
void testPopularityScaling()
void testEqualityOperator()
Contains all classes and functions of the TagInfo library.
The Popularity class contains a value for ID3v2's "Popularimeter" field.
std::string user
The user who gave the rating / played the file, e.g. identified by e-mail address.
double rating
The rating on a tag type specific scale.
CPPUNIT_TEST_SUITE_REGISTRATION(TagValueTests)