mirror of
https://github.com/taglib/taglib.git
synced 2025-05-25 12:10:26 -04:00
Fix issues reported by CppCheck
Many shadowFunction, some useStlAlgorithm, and others. cppcheck --enable=all --inline-suppr \ --suppress=noExplicitConstructor --suppress=unusedFunction \ --suppress=missingIncludeSystem --project=compile_commands.json
This commit is contained in:
parent
131918333b
commit
8b3f1a459e
@ -58,16 +58,16 @@ int main(int argc, char *argv[])
|
||||
TagLib::PropertyMap tags = f.properties();
|
||||
if(!tags.isEmpty()) {
|
||||
unsigned int longest = 0;
|
||||
for(auto i = tags.cbegin(); i != tags.cend(); ++i) {
|
||||
if (i->first.size() > longest) {
|
||||
longest = i->first.size();
|
||||
for(auto j = tags.cbegin(); j != tags.cend(); ++j) {
|
||||
if (j->first.size() > longest) {
|
||||
longest = j->first.size();
|
||||
}
|
||||
}
|
||||
|
||||
cout << "-- TAG (properties) --" << endl;
|
||||
for(auto i = tags.cbegin(); i != tags.cend(); ++i) {
|
||||
for(auto j = i->second.begin(); j != i->second.end(); ++j) {
|
||||
cout << left << std::setfill(' ') << std::setw(longest) << i->first << " - " << '"' << *j << '"' << endl;
|
||||
for(auto j = tags.cbegin(); j != tags.cend(); ++j) {
|
||||
for(auto k = j->second.begin(); k != j->second.end(); ++k) {
|
||||
cout << left << std::setfill(' ') << std::setw(longest) << j->first << " - " << '"' << *k << '"' << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,17 +34,16 @@
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
int seconds;
|
||||
int minutes;
|
||||
TagLib_File *file;
|
||||
TagLib_Tag *tag;
|
||||
const TagLib_AudioProperties *properties;
|
||||
char **propertiesMap;
|
||||
char **complexKeys;
|
||||
|
||||
taglib_set_strings_unicode(1);
|
||||
|
||||
for(i = 1; i < argc; i++) {
|
||||
TagLib_File *file;
|
||||
TagLib_Tag *tag;
|
||||
const TagLib_AudioProperties *properties;
|
||||
char **propertiesMap;
|
||||
char **complexKeys;
|
||||
|
||||
printf("******************** \"%s\" ********************\n", argv[i]);
|
||||
|
||||
file = taglib_file_new(argv[i]);
|
||||
@ -62,9 +61,9 @@ int main(int argc, char *argv[])
|
||||
printf("title - \"%s\"\n", taglib_tag_title(tag));
|
||||
printf("artist - \"%s\"\n", taglib_tag_artist(tag));
|
||||
printf("album - \"%s\"\n", taglib_tag_album(tag));
|
||||
printf("year - \"%i\"\n", taglib_tag_year(tag));
|
||||
printf("year - \"%u\"\n", taglib_tag_year(tag));
|
||||
printf("comment - \"%s\"\n", taglib_tag_comment(tag));
|
||||
printf("track - \"%i\"\n", taglib_tag_track(tag));
|
||||
printf("track - \"%u\"\n", taglib_tag_track(tag));
|
||||
printf("genre - \"%s\"\n", taglib_tag_genre(tag));
|
||||
}
|
||||
|
||||
@ -96,10 +95,10 @@ int main(int argc, char *argv[])
|
||||
if(complexKeys != NULL) {
|
||||
char **keyPtr = complexKeys;
|
||||
while(*keyPtr) {
|
||||
TagLib_Complex_Property_Attribute*** properties =
|
||||
TagLib_Complex_Property_Attribute*** props =
|
||||
taglib_complex_property_get(file, *keyPtr);
|
||||
if(properties != NULL) {
|
||||
TagLib_Complex_Property_Attribute*** propPtr = properties;
|
||||
if(props != NULL) {
|
||||
TagLib_Complex_Property_Attribute*** propPtr = props;
|
||||
while(*propPtr) {
|
||||
TagLib_Complex_Property_Attribute** attrPtr = *propPtr;
|
||||
printf("%s:\n", *keyPtr);
|
||||
@ -153,7 +152,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
++propPtr;
|
||||
}
|
||||
taglib_complex_property_free(properties);
|
||||
taglib_complex_property_free(props);
|
||||
}
|
||||
++keyPtr;
|
||||
}
|
||||
@ -161,8 +160,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if(properties != NULL) {
|
||||
seconds = taglib_audioproperties_length(properties) % 60;
|
||||
minutes = (taglib_audioproperties_length(properties) - seconds) / 60;
|
||||
int seconds = taglib_audioproperties_length(properties) % 60;
|
||||
int minutes = (taglib_audioproperties_length(properties) - seconds) / 60;
|
||||
|
||||
printf("-- AUDIO --\n");
|
||||
printf("bitrate - %i\n", taglib_audioproperties_bitrate(properties));
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "apeitem.h"
|
||||
|
||||
#include <utility>
|
||||
#include <numeric>
|
||||
|
||||
#include "tdebug.h"
|
||||
|
||||
@ -175,9 +176,10 @@ int APE::Item::size() const
|
||||
switch(d->type) {
|
||||
case Text:
|
||||
if(!d->text.isEmpty()) {
|
||||
for(const auto &t : std::as_const(d->text))
|
||||
result += 1 + t.data(String::UTF8).size();
|
||||
result -= 1;
|
||||
result = std::accumulate(d->text.cbegin(), d->text.cend(), result,
|
||||
[](int sz, const String &t) {
|
||||
return sz + 1 + t.data(String::UTF8).size();
|
||||
}) - 1;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -238,22 +240,22 @@ void APE::Item::parse(const ByteVector &data)
|
||||
|
||||
d->key = String(&data[8], String::Latin1);
|
||||
|
||||
const ByteVector value = data.mid(8 + d->key.size() + 1, valueLength);
|
||||
const ByteVector val = data.mid(8 + d->key.size() + 1, valueLength);
|
||||
|
||||
setReadOnly(flags & 1);
|
||||
setType(static_cast<ItemTypes>((flags >> 1) & 3));
|
||||
|
||||
if(Text == d->type)
|
||||
d->text = StringList(ByteVectorList::split(value, '\0'), String::UTF8);
|
||||
d->text = StringList(ByteVectorList::split(val, '\0'), String::UTF8);
|
||||
else
|
||||
d->value = value;
|
||||
d->value = val;
|
||||
}
|
||||
|
||||
ByteVector APE::Item::render() const
|
||||
{
|
||||
ByteVector data;
|
||||
unsigned int flags = ((d->readOnly) ? 1 : 0) | (d->type << 1);
|
||||
ByteVector value;
|
||||
ByteVector val;
|
||||
|
||||
if(isEmpty())
|
||||
return data;
|
||||
@ -261,21 +263,21 @@ ByteVector APE::Item::render() const
|
||||
if(d->type == Text) {
|
||||
auto it = d->text.cbegin();
|
||||
|
||||
value.append(it->data(String::UTF8));
|
||||
val.append(it->data(String::UTF8));
|
||||
for(it = std::next(it); it != d->text.cend(); ++it) {
|
||||
value.append('\0');
|
||||
value.append(it->data(String::UTF8));
|
||||
val.append('\0');
|
||||
val.append(it->data(String::UTF8));
|
||||
}
|
||||
d->value = value;
|
||||
d->value = val;
|
||||
}
|
||||
else
|
||||
value.append(d->value);
|
||||
val.append(d->value);
|
||||
|
||||
data.append(ByteVector::fromUInt(value.size(), false));
|
||||
data.append(ByteVector::fromUInt(val.size(), false));
|
||||
data.append(ByteVector::fromUInt(flags, false));
|
||||
data.append(d->key.data(String::Latin1));
|
||||
data.append(ByteVector('\0'));
|
||||
data.append(value);
|
||||
data.append(val);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -115,21 +115,21 @@ void APE::Properties::read(File *file, offset_t streamLength)
|
||||
{
|
||||
// First, we assume that the file pointer is set at the first descriptor.
|
||||
offset_t offset = file->tell();
|
||||
int version = headerVersion(file->readBlock(6));
|
||||
int vers = headerVersion(file->readBlock(6));
|
||||
|
||||
// Next, we look for the descriptor.
|
||||
if(version < 0) {
|
||||
if(vers < 0) {
|
||||
offset = file->find("MAC ", offset);
|
||||
file->seek(offset);
|
||||
version = headerVersion(file->readBlock(6));
|
||||
vers = headerVersion(file->readBlock(6));
|
||||
}
|
||||
|
||||
if(version < 0) {
|
||||
if(vers < 0) {
|
||||
debug("APE::Properties::read() -- APE descriptor not found");
|
||||
return;
|
||||
}
|
||||
|
||||
d->version = version;
|
||||
d->version = vers;
|
||||
|
||||
if(d->version >= 3980)
|
||||
analyzeCurrent(file);
|
||||
|
@ -102,44 +102,44 @@ ByteVector APE::Tag::fileIdentifier()
|
||||
|
||||
String APE::Tag::title() const
|
||||
{
|
||||
Item value = d->itemListMap.value("TITLE");
|
||||
return value.isEmpty() ? String() : joinTagValues(value.values());
|
||||
Item val = d->itemListMap.value("TITLE");
|
||||
return val.isEmpty() ? String() : joinTagValues(val.values());
|
||||
}
|
||||
|
||||
String APE::Tag::artist() const
|
||||
{
|
||||
Item value = d->itemListMap.value("ARTIST");
|
||||
return value.isEmpty() ? String() : joinTagValues(value.values());
|
||||
Item val = d->itemListMap.value("ARTIST");
|
||||
return val.isEmpty() ? String() : joinTagValues(val.values());
|
||||
}
|
||||
|
||||
String APE::Tag::album() const
|
||||
{
|
||||
Item value = d->itemListMap.value("ALBUM");
|
||||
return value.isEmpty() ? String() : joinTagValues(value.values());
|
||||
Item val = d->itemListMap.value("ALBUM");
|
||||
return val.isEmpty() ? String() : joinTagValues(val.values());
|
||||
}
|
||||
|
||||
String APE::Tag::comment() const
|
||||
{
|
||||
Item value = d->itemListMap.value("COMMENT");
|
||||
return value.isEmpty() ? String() : joinTagValues(value.values());
|
||||
Item val = d->itemListMap.value("COMMENT");
|
||||
return val.isEmpty() ? String() : joinTagValues(val.values());
|
||||
}
|
||||
|
||||
String APE::Tag::genre() const
|
||||
{
|
||||
Item value = d->itemListMap.value("GENRE");
|
||||
return value.isEmpty() ? String() : joinTagValues(value.values());
|
||||
Item val = d->itemListMap.value("GENRE");
|
||||
return val.isEmpty() ? String() : joinTagValues(val.values());
|
||||
}
|
||||
|
||||
unsigned int APE::Tag::year() const
|
||||
{
|
||||
Item value = d->itemListMap.value("YEAR");
|
||||
return value.isEmpty() ? 0 : value.toString().toInt();
|
||||
Item val = d->itemListMap.value("YEAR");
|
||||
return val.isEmpty() ? 0 : val.toString().toInt();
|
||||
}
|
||||
|
||||
unsigned int APE::Tag::track() const
|
||||
{
|
||||
Item value = d->itemListMap.value("TRACK");
|
||||
return value.isEmpty() ? 0 : value.toString().toInt();
|
||||
Item val = d->itemListMap.value("TRACK");
|
||||
return val.isEmpty() ? 0 : val.toString().toInt();
|
||||
}
|
||||
|
||||
void APE::Tag::setTitle(const String &s)
|
||||
@ -229,13 +229,13 @@ void APE::Tag::removeUnsupportedProperties(const StringList &properties)
|
||||
|
||||
PropertyMap APE::Tag::setProperties(const PropertyMap &origProps)
|
||||
{
|
||||
PropertyMap properties(origProps); // make a local copy that can be modified
|
||||
PropertyMap props(origProps); // make a local copy that can be modified
|
||||
|
||||
// see comment in properties()
|
||||
for(const auto &[k, t] : keyConversions)
|
||||
if(properties.contains(k)) {
|
||||
properties.insert(t, properties[k]);
|
||||
properties.erase(k);
|
||||
if(props.contains(k)) {
|
||||
props.insert(t, props[k]);
|
||||
props.erase(k);
|
||||
}
|
||||
|
||||
// first check if tags need to be removed completely
|
||||
@ -243,7 +243,7 @@ PropertyMap APE::Tag::setProperties(const PropertyMap &origProps)
|
||||
for(const auto &[k, t] : std::as_const(itemListMap())) {
|
||||
String key = k.upper();
|
||||
// only remove if a) key is valid, b) type is text, c) key not contained in new properties
|
||||
if(!key.isEmpty() && t.type() == APE::Item::Text && !properties.contains(key))
|
||||
if(!key.isEmpty() && t.type() == APE::Item::Text && !props.contains(key))
|
||||
toRemove.append(k);
|
||||
}
|
||||
|
||||
@ -252,15 +252,15 @@ PropertyMap APE::Tag::setProperties(const PropertyMap &origProps)
|
||||
|
||||
// now sync in the "forward direction"
|
||||
PropertyMap invalid;
|
||||
for(const auto &[tagName, value] : std::as_const(properties)) {
|
||||
for(const auto &[tagName, val] : std::as_const(props)) {
|
||||
if(!checkKey(tagName))
|
||||
invalid.insert(tagName, value);
|
||||
else if(!(itemListMap().contains(tagName)) || !(itemListMap()[tagName].values() == value)) {
|
||||
if(value.isEmpty())
|
||||
invalid.insert(tagName, val);
|
||||
else if(!(itemListMap().contains(tagName)) || !(itemListMap()[tagName].values() == val)) {
|
||||
if(val.isEmpty())
|
||||
removeItem(tagName);
|
||||
else {
|
||||
addValue(tagName, *value.begin(), true);
|
||||
for(auto it = std::next(value.begin()); it != value.end(); ++it)
|
||||
addValue(tagName, *val.begin(), true);
|
||||
for(auto it = std::next(val.begin()); it != val.end(); ++it)
|
||||
addValue(tagName, *it, false);
|
||||
}
|
||||
}
|
||||
@ -280,7 +280,7 @@ StringList APE::Tag::complexPropertyKeys() const
|
||||
|
||||
List<VariantMap> APE::Tag::complexProperties(const String &key) const
|
||||
{
|
||||
List<VariantMap> properties;
|
||||
List<VariantMap> props;
|
||||
const String uppercaseKey = key.upper();
|
||||
if(uppercaseKey == "PICTURE") {
|
||||
const StringList itemNames = StringList(FRONT_COVER).append(BACK_COVER);
|
||||
@ -306,12 +306,12 @@ List<VariantMap> APE::Tag::complexProperties(const String &key) const
|
||||
}
|
||||
property.insert("pictureType",
|
||||
itemName == BACK_COVER ? "Back Cover" : "Front Cover");
|
||||
properties.append(property);
|
||||
props.append(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
return props;
|
||||
}
|
||||
|
||||
bool APE::Tag::setComplexProperties(const String &key, const List<VariantMap> &value)
|
||||
|
@ -369,8 +369,8 @@ void ASF::File::FilePrivate::HeaderExtensionObject::parse(ASF::File *file, unsig
|
||||
long long dataSize = readDWORD(file);
|
||||
long long dataPos = 0;
|
||||
while(dataPos < dataSize) {
|
||||
ByteVector guid = file->readBlock(16);
|
||||
if(guid.size() != 16) {
|
||||
ByteVector uid = file->readBlock(16);
|
||||
if(uid.size() != 16) {
|
||||
file->setValid(false);
|
||||
break;
|
||||
}
|
||||
@ -381,16 +381,16 @@ void ASF::File::FilePrivate::HeaderExtensionObject::parse(ASF::File *file, unsig
|
||||
break;
|
||||
}
|
||||
BaseObject *obj;
|
||||
if(guid == metadataGuid) {
|
||||
if(uid == metadataGuid) {
|
||||
file->d->metadataObject = new MetadataObject();
|
||||
obj = file->d->metadataObject;
|
||||
}
|
||||
else if(guid == metadataLibraryGuid) {
|
||||
else if(uid == metadataLibraryGuid) {
|
||||
file->d->metadataLibraryObject = new MetadataLibraryObject();
|
||||
obj = file->d->metadataLibraryObject;
|
||||
}
|
||||
else {
|
||||
obj = new UnknownObject(guid);
|
||||
obj = new UnknownObject(uid);
|
||||
}
|
||||
obj->parse(file, static_cast<unsigned int>(size));
|
||||
objects.append(obj);
|
||||
|
@ -197,9 +197,9 @@ ASF::AttributeList ASF::Tag::attribute(const String &name) const
|
||||
|
||||
void ASF::Tag::setAttribute(const String &name, const Attribute &attribute)
|
||||
{
|
||||
AttributeList value;
|
||||
value.append(attribute);
|
||||
d->attributeListMap.insert(name, value);
|
||||
AttributeList val;
|
||||
val.append(attribute);
|
||||
d->attributeListMap.insert(name, val);
|
||||
}
|
||||
|
||||
void ASF::Tag::setAttribute(const String &name, const AttributeList &values)
|
||||
@ -313,15 +313,15 @@ PropertyMap ASF::Tag::properties() const
|
||||
for(const auto &[k, attributes] : std::as_const(d->attributeListMap)) {
|
||||
const String key = translateKey(k);
|
||||
if(!key.isEmpty()) {
|
||||
for(const auto &attribute : attributes) {
|
||||
for(const auto &attr : attributes) {
|
||||
if(key == "TRACKNUMBER") {
|
||||
if(attribute.type() == ASF::Attribute::DWordType)
|
||||
props.insert(key, String::number(attribute.toUInt()));
|
||||
if(attr.type() == ASF::Attribute::DWordType)
|
||||
props.insert(key, String::number(attr.toUInt()));
|
||||
else
|
||||
props.insert(key, attribute.toString());
|
||||
props.insert(key, attr.toString());
|
||||
}
|
||||
else {
|
||||
props.insert(key, attribute.toString());
|
||||
props.insert(key, attr.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -373,8 +373,8 @@ PropertyMap ASF::Tag::setProperties(const PropertyMap &props)
|
||||
if(reverseKeyMap.contains(prop)) {
|
||||
String name = reverseKeyMap[prop];
|
||||
removeItem(name);
|
||||
for(const auto &attribute : attributes) {
|
||||
addAttribute(name, attribute);
|
||||
for(const auto &attr : attributes) {
|
||||
addAttribute(name, attr);
|
||||
}
|
||||
}
|
||||
else if(prop == "TITLE") {
|
||||
@ -408,22 +408,22 @@ StringList ASF::Tag::complexPropertyKeys() const
|
||||
|
||||
List<VariantMap> ASF::Tag::complexProperties(const String &key) const
|
||||
{
|
||||
List<VariantMap> properties;
|
||||
List<VariantMap> props;
|
||||
const String uppercaseKey = key.upper();
|
||||
if(uppercaseKey == "PICTURE") {
|
||||
const AttributeList pictures = d->attributeListMap.value("WM/Picture");
|
||||
for(const Attribute &attribute : pictures) {
|
||||
ASF::Picture picture = attribute.toPicture();
|
||||
for(const Attribute &attr : pictures) {
|
||||
ASF::Picture picture = attr.toPicture();
|
||||
VariantMap property;
|
||||
property.insert("data", picture.picture());
|
||||
property.insert("mimeType", picture.mimeType());
|
||||
property.insert("description", picture.description());
|
||||
property.insert("pictureType",
|
||||
ASF::Picture::typeToString(picture.type()));
|
||||
properties.append(property);
|
||||
props.append(property);
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
return props;
|
||||
}
|
||||
|
||||
bool ASF::Tag::setComplexProperties(const String &key, const List<VariantMap> &value)
|
||||
|
@ -128,18 +128,18 @@ PropertyMap DSDIFF::DIIN::Tag::properties() const
|
||||
|
||||
PropertyMap DSDIFF::DIIN::Tag::setProperties(const PropertyMap &origProps)
|
||||
{
|
||||
PropertyMap properties(origProps);
|
||||
properties.removeEmpty();
|
||||
PropertyMap props(origProps);
|
||||
props.removeEmpty();
|
||||
StringList oneValueSet;
|
||||
|
||||
if(properties.contains("TITLE")) {
|
||||
d->title = properties["TITLE"].front();
|
||||
if(props.contains("TITLE")) {
|
||||
d->title = props["TITLE"].front();
|
||||
oneValueSet.append("TITLE");
|
||||
} else
|
||||
d->title.clear();
|
||||
|
||||
if(properties.contains("ARTIST")) {
|
||||
d->artist = properties["ARTIST"].front();
|
||||
if(props.contains("ARTIST")) {
|
||||
d->artist = props["ARTIST"].front();
|
||||
oneValueSet.append("ARTIST");
|
||||
} else
|
||||
d->artist.clear();
|
||||
@ -147,10 +147,10 @@ PropertyMap DSDIFF::DIIN::Tag::setProperties(const PropertyMap &origProps)
|
||||
// for each tag that has been set above, remove the first entry in the corresponding
|
||||
// value list. The others will be returned as unsupported by this format.
|
||||
for(const auto &entry : std::as_const(oneValueSet)) {
|
||||
if(properties[entry].size() == 1)
|
||||
properties.erase(entry);
|
||||
if(props[entry].size() == 1)
|
||||
props.erase(entry);
|
||||
else
|
||||
properties[entry].erase(properties[entry].begin());
|
||||
props[entry].erase(props[entry].begin());
|
||||
}
|
||||
return properties;
|
||||
return props;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "flacfile.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#include "tdebug.h"
|
||||
@ -144,11 +145,11 @@ StringList FLAC::File::complexPropertyKeys() const
|
||||
{
|
||||
StringList keys = TagLib::File::complexPropertyKeys();
|
||||
if(!keys.contains("PICTURE")) {
|
||||
for(const auto &block : std::as_const(d->blocks)) {
|
||||
if(dynamic_cast<Picture *>(block) != nullptr) {
|
||||
keys.append("PICTURE");
|
||||
break;
|
||||
}
|
||||
if(std::any_of(d->blocks.cbegin(), d->blocks.cend(),
|
||||
[](MetadataBlock *block) {
|
||||
return dynamic_cast<Picture *>(block) != nullptr;
|
||||
})) {
|
||||
keys.append("PICTURE");
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
@ -158,7 +159,7 @@ List<VariantMap> FLAC::File::complexProperties(const String &key) const
|
||||
{
|
||||
const String uppercaseKey = key.upper();
|
||||
if(uppercaseKey == "PICTURE") {
|
||||
List<VariantMap> properties;
|
||||
List<VariantMap> props;
|
||||
for(const auto &block : std::as_const(d->blocks)) {
|
||||
if(auto picture = dynamic_cast<Picture *>(block)) {
|
||||
VariantMap property;
|
||||
@ -171,10 +172,10 @@ List<VariantMap> FLAC::File::complexProperties(const String &key) const
|
||||
property.insert("height", picture->height());
|
||||
property.insert("numColors", picture->numColors());
|
||||
property.insert("colorDepth", picture->colorDepth());
|
||||
properties.append(property);
|
||||
props.append(property);
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
return props;
|
||||
}
|
||||
return TagLib::File::complexProperties(key);
|
||||
}
|
||||
|
@ -135,23 +135,23 @@ PropertyMap Mod::Tag::properties() const
|
||||
|
||||
PropertyMap Mod::Tag::setProperties(const PropertyMap &origProps)
|
||||
{
|
||||
PropertyMap properties(origProps);
|
||||
properties.removeEmpty();
|
||||
PropertyMap props(origProps);
|
||||
props.removeEmpty();
|
||||
StringList oneValueSet;
|
||||
if(properties.contains("TITLE")) {
|
||||
d->title = properties["TITLE"].front();
|
||||
if(props.contains("TITLE")) {
|
||||
d->title = props["TITLE"].front();
|
||||
oneValueSet.append("TITLE");
|
||||
} else
|
||||
d->title.clear();
|
||||
|
||||
if(properties.contains("COMMENT")) {
|
||||
d->comment = properties["COMMENT"].front();
|
||||
if(props.contains("COMMENT")) {
|
||||
d->comment = props["COMMENT"].front();
|
||||
oneValueSet.append("COMMENT");
|
||||
} else
|
||||
d->comment.clear();
|
||||
|
||||
if(properties.contains("TRACKERNAME")) {
|
||||
d->trackerName = properties["TRACKERNAME"].front();
|
||||
if(props.contains("TRACKERNAME")) {
|
||||
d->trackerName = props["TRACKERNAME"].front();
|
||||
oneValueSet.append("TRACKERNAME");
|
||||
} else
|
||||
d->trackerName.clear();
|
||||
@ -159,10 +159,10 @@ PropertyMap Mod::Tag::setProperties(const PropertyMap &origProps)
|
||||
// for each tag that has been set above, remove the first entry in the corresponding
|
||||
// value list. The others will be returned as unsupported by this format.
|
||||
for(const auto &entry : std::as_const(oneValueSet)) {
|
||||
if(properties[entry].size() == 1)
|
||||
properties.erase(entry);
|
||||
if(props[entry].size() == 1)
|
||||
props.erase(entry);
|
||||
else
|
||||
properties[entry].erase(properties[entry].begin());
|
||||
props[entry].erase(props[entry].begin());
|
||||
}
|
||||
return properties;
|
||||
return props;
|
||||
}
|
||||
|
@ -132,12 +132,9 @@ MP4::Atom::find(const char *name1, const char *name2, const char *name3, const c
|
||||
if(name1 == nullptr) {
|
||||
return this;
|
||||
}
|
||||
for(const auto &child : std::as_const(children)) {
|
||||
if(child->name == name1) {
|
||||
return child->find(name2, name3, name4);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
auto it = std::find_if(children.cbegin(), children.cend(),
|
||||
[&name1](Atom *child) { return child->name == name1; });
|
||||
return it != children.cend() ? (*it)->find(name2, name3, name4) : nullptr;
|
||||
}
|
||||
|
||||
MP4::AtomList
|
||||
@ -162,12 +159,9 @@ MP4::Atom::path(MP4::AtomList &path, const char *name1, const char *name2, const
|
||||
if(name1 == nullptr) {
|
||||
return true;
|
||||
}
|
||||
for(const auto &child : std::as_const(children)) {
|
||||
if(child->name == name1) {
|
||||
return child->path(path, name2, name3);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
auto it = std::find_if(children.cbegin(), children.cend(),
|
||||
[&name1](Atom *child) { return child->name == name1; });
|
||||
return it != children.cend() ? (*it)->path(path, name2, name3) : false;
|
||||
}
|
||||
|
||||
MP4::Atoms::Atoms(File *file)
|
||||
@ -190,25 +184,22 @@ MP4::Atoms::~Atoms() = default;
|
||||
MP4::Atom *
|
||||
MP4::Atoms::find(const char *name1, const char *name2, const char *name3, const char *name4)
|
||||
{
|
||||
for(const auto &atom : std::as_const(atoms)) {
|
||||
if(atom->name == name1) {
|
||||
return atom->find(name2, name3, name4);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
auto it = std::find_if(atoms.cbegin(), atoms.cend(),
|
||||
[&name1](Atom *atom) { return atom->name == name1; });
|
||||
return it != atoms.cend() ? (*it)->find(name2, name3, name4) : nullptr;
|
||||
}
|
||||
|
||||
MP4::AtomList
|
||||
MP4::Atoms::path(const char *name1, const char *name2, const char *name3, const char *name4)
|
||||
{
|
||||
MP4::AtomList path;
|
||||
for(const auto &atom : std::as_const(atoms)) {
|
||||
if(atom->name == name1) {
|
||||
if(!atom->path(path, name2, name3, name4)) {
|
||||
path.clear();
|
||||
}
|
||||
return path;
|
||||
auto it = std::find_if(atoms.cbegin(), atoms.cend(),
|
||||
[&name1](Atom *atom) { return atom->name == name1; });
|
||||
if(it != atoms.cend()) {
|
||||
if(!(*it)->path(path, name2, name3, name4)) {
|
||||
path.clear();
|
||||
}
|
||||
return path;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
@ -74,9 +74,9 @@ MP4::Tag::Tag(TagLib::File *file, MP4::Atoms *atoms,
|
||||
for(const auto &atom : std::as_const(ilst->children)) {
|
||||
file->seek(atom->offset + 8);
|
||||
ByteVector data = d->file->readBlock(atom->length - 8);
|
||||
const auto &[name, item] = d->factory->parseItem(atom, data);
|
||||
if (item.isValid()) {
|
||||
addItem(name, item);
|
||||
const auto &[name, itm] = d->factory->parseItem(atom, data);
|
||||
if (itm.isValid()) {
|
||||
addItem(name, itm);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -102,8 +102,8 @@ bool
|
||||
MP4::Tag::save()
|
||||
{
|
||||
ByteVector data;
|
||||
for(const auto &[name, item] : std::as_const(d->items)) {
|
||||
data.append(d->factory->renderItem(name, item));
|
||||
for(const auto &[name, itm] : std::as_const(d->items)) {
|
||||
data.append(d->factory->renderItem(name, itm));
|
||||
}
|
||||
data = renderAtom("ilst", data);
|
||||
|
||||
@ -473,9 +473,9 @@ PropertyMap MP4::Tag::properties() const
|
||||
{
|
||||
PropertyMap props;
|
||||
for(const auto &[k, t] : std::as_const(d->items)) {
|
||||
auto [key, value] = d->factory->itemToProperty(k.data(String::Latin1), t);
|
||||
auto [key, val] = d->factory->itemToProperty(k.data(String::Latin1), t);
|
||||
if(!key.isEmpty()) {
|
||||
props[key] = value;
|
||||
props[key] = val;
|
||||
}
|
||||
else {
|
||||
props.addUnsupportedData(k);
|
||||
@ -501,9 +501,9 @@ PropertyMap MP4::Tag::setProperties(const PropertyMap &props)
|
||||
|
||||
PropertyMap ignoredProps;
|
||||
for(const auto &[prop, val] : props) {
|
||||
auto [name, item] = d->factory->itemFromProperty(prop, val);
|
||||
if(item.isValid()) {
|
||||
d->items[name] = item;
|
||||
auto [name, itm] = d->factory->itemFromProperty(prop, val);
|
||||
if(itm.isValid()) {
|
||||
d->items[name] = itm;
|
||||
}
|
||||
else {
|
||||
ignoredProps.insert(prop, val);
|
||||
@ -524,7 +524,7 @@ StringList MP4::Tag::complexPropertyKeys() const
|
||||
|
||||
List<VariantMap> MP4::Tag::complexProperties(const String &key) const
|
||||
{
|
||||
List<VariantMap> properties;
|
||||
List<VariantMap> props;
|
||||
const String uppercaseKey = key.upper();
|
||||
if(uppercaseKey == "PICTURE") {
|
||||
const CoverArtList pictures = d->items.value("covr").toCoverArtList();
|
||||
@ -550,10 +550,10 @@ List<VariantMap> MP4::Tag::complexProperties(const String &key) const
|
||||
VariantMap property;
|
||||
property.insert("data", picture.data());
|
||||
property.insert("mimeType", mimeType);
|
||||
properties.append(property);
|
||||
props.append(property);
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
return props;
|
||||
}
|
||||
|
||||
bool MP4::Tag::setComplexProperties(const String &key, const List<VariantMap> &value)
|
||||
|
@ -272,8 +272,8 @@ int ID3v1::genreIndex(const String &name)
|
||||
std::pair(L"BritPop", 132),
|
||||
std::pair(L"Negerpunk", 133),
|
||||
};
|
||||
for(const auto &[genre, code] : fixUpGenres) {
|
||||
if(name == genre)
|
||||
for(const auto &[genreName, code] : fixUpGenres) {
|
||||
if(name == genreName)
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -340,13 +340,15 @@ PropertyMap TextIdentificationFrame::makeTMCLProperties() const
|
||||
const StringList l = fieldList();
|
||||
for(auto it = l.begin(); it != l.end(); ++it) {
|
||||
String instrument = it->upper();
|
||||
if(instrument.isEmpty()) {
|
||||
// ++it == l.end() is not possible with size check above,
|
||||
// verified to silence cppcheck.
|
||||
if(instrument.isEmpty() || ++it == l.end()) {
|
||||
// instrument is not a valid key -> frame unsupported
|
||||
map.clear();
|
||||
map.addUnsupportedData(frameID());
|
||||
return map;
|
||||
}
|
||||
map.insert(L"PERFORMER:" + instrument, (++it)->split(","));
|
||||
map.insert(L"PERFORMER:" + instrument, it->split(","));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ std::pair<Frame::Header *, bool> FrameFactory::prepareFrameHeader(
|
||||
}
|
||||
|
||||
#ifndef NO_ITUNES_HACKS
|
||||
if(version == 3 && frameID.size() == 4 && frameID[3] == '\0') {
|
||||
if(version == 3 && frameID[3] == '\0') {
|
||||
// iTunes v2.3 tags store v2.2 frames - convert now
|
||||
frameID = frameID.mid(0, 3);
|
||||
header->setFrameID(frameID);
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "id3v2header.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <bitset>
|
||||
|
||||
#include "tstring.h"
|
||||
@ -197,12 +198,11 @@ void Header::parse(const ByteVector &data)
|
||||
return;
|
||||
}
|
||||
|
||||
for(const auto &size : sizeData) {
|
||||
if(static_cast<unsigned char>(size) >= 128) {
|
||||
d->tagSize = 0;
|
||||
debug("TagLib::ID3v2::Header::parse() - One of the size bytes in the id3v2 header was greater than the allowed 128.");
|
||||
return;
|
||||
}
|
||||
if(std::any_of(sizeData.cbegin(), sizeData.cend(),
|
||||
[](unsigned char size) { return size >= 128; })) {
|
||||
d->tagSize = 0;
|
||||
debug("TagLib::ID3v2::Header::parse() - One of the size bytes in the id3v2 header was greater than the allowed 128.");
|
||||
return;
|
||||
}
|
||||
|
||||
// The first three bytes, data[0..2], are the File Identifier, "ID3". (structure 3.1 "file identifier")
|
||||
|
@ -146,10 +146,10 @@ String ID3v2::Tag::comment() const
|
||||
if(comments.isEmpty())
|
||||
return String();
|
||||
|
||||
for(const auto &comment : comments) {
|
||||
auto frame = dynamic_cast<CommentsFrame *>(comment);
|
||||
for(const auto &commFrame : comments) {
|
||||
auto frame = dynamic_cast<CommentsFrame *>(commFrame);
|
||||
if(frame && frame->description().isEmpty())
|
||||
return comment->toString();
|
||||
return commFrame->toString();
|
||||
}
|
||||
|
||||
return comments.front()->toString();
|
||||
@ -234,10 +234,10 @@ void ID3v2::Tag::setComment(const String &s)
|
||||
const FrameList &comments = d->frameListMap["COMM"];
|
||||
|
||||
if(!comments.isEmpty()) {
|
||||
for(const auto &comment : comments) {
|
||||
auto frame = dynamic_cast<CommentsFrame *>(comment);
|
||||
for(const auto &commFrame : comments) {
|
||||
auto frame = dynamic_cast<CommentsFrame *>(commFrame);
|
||||
if(frame && frame->description().isEmpty()) {
|
||||
comment->setText(s);
|
||||
commFrame->setText(s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -408,10 +408,10 @@ PropertyMap ID3v2::Tag::setProperties(const PropertyMap &origProps)
|
||||
FrameList framesToDelete;
|
||||
// we split up the PropertyMap into the "normal" keys and the "complicated" ones,
|
||||
// which are those according to TIPL or TMCL frames.
|
||||
PropertyMap properties;
|
||||
PropertyMap singleFrameProperties;
|
||||
PropertyMap tiplProperties;
|
||||
PropertyMap tmclProperties;
|
||||
Frame::splitProperties(origProps, properties, tiplProperties, tmclProperties);
|
||||
Frame::splitProperties(origProps, singleFrameProperties, tiplProperties, tmclProperties);
|
||||
for(const auto &[tag, frames] : std::as_const(frameListMap())) {
|
||||
for(const auto &frame : frames) {
|
||||
PropertyMap frameProperties = frame->asProperties();
|
||||
@ -427,10 +427,10 @@ PropertyMap ID3v2::Tag::setProperties(const PropertyMap &origProps)
|
||||
else
|
||||
tmclProperties.erase(frameProperties);
|
||||
}
|
||||
else if(!properties.contains(frameProperties))
|
||||
else if(!singleFrameProperties.contains(frameProperties))
|
||||
framesToDelete.append(frame);
|
||||
else
|
||||
properties.erase(frameProperties);
|
||||
singleFrameProperties.erase(frameProperties);
|
||||
}
|
||||
}
|
||||
for(const auto &frame : std::as_const(framesToDelete))
|
||||
@ -444,7 +444,7 @@ PropertyMap ID3v2::Tag::setProperties(const PropertyMap &origProps)
|
||||
if(!tmclProperties.isEmpty())
|
||||
addFrame(TextIdentificationFrame::createTMCLFrame(tmclProperties));
|
||||
// now create the "one key per frame" frames
|
||||
for(const auto &[tag, frames] : std::as_const(properties))
|
||||
for(const auto &[tag, frames] : std::as_const(singleFrameProperties))
|
||||
addFrame(d->factory->createFrameForProperty(tag, frames));
|
||||
return PropertyMap(); // ID3 implements the complete PropertyMap interface, so an empty map is returned
|
||||
}
|
||||
@ -463,7 +463,7 @@ StringList ID3v2::Tag::complexPropertyKeys() const
|
||||
|
||||
List<VariantMap> ID3v2::Tag::complexProperties(const String &key) const
|
||||
{
|
||||
List<VariantMap> properties;
|
||||
List<VariantMap> props;
|
||||
const String uppercaseKey = key.upper();
|
||||
if(uppercaseKey == "PICTURE") {
|
||||
const FrameList pictures = d->frameListMap.value("APIC");
|
||||
@ -475,7 +475,7 @@ List<VariantMap> ID3v2::Tag::complexProperties(const String &key) const
|
||||
property.insert("description", picture->description());
|
||||
property.insert("pictureType",
|
||||
AttachedPictureFrame::typeToString(picture->type()));
|
||||
properties.append(property);
|
||||
props.append(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -488,11 +488,11 @@ List<VariantMap> ID3v2::Tag::complexProperties(const String &key) const
|
||||
property.insert("mimeType", geob->mimeType());
|
||||
property.insert("description", geob->description());
|
||||
property.insert("fileName", geob->fileName());
|
||||
properties.append(property);
|
||||
props.append(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
return props;
|
||||
}
|
||||
|
||||
bool ID3v2::Tag::setComplexProperties(const String &key, const List<VariantMap> &value)
|
||||
@ -679,12 +679,12 @@ ByteVector ID3v2::Tag::render(Version version) const
|
||||
FrameList newFrames;
|
||||
newFrames.setAutoDelete(true);
|
||||
|
||||
FrameList frameList;
|
||||
FrameList frames;
|
||||
if(version == v4) {
|
||||
frameList = d->frameList;
|
||||
frames = d->frameList;
|
||||
}
|
||||
else {
|
||||
downgradeFrames(&frameList, &newFrames);
|
||||
downgradeFrames(&frames, &newFrames);
|
||||
}
|
||||
|
||||
// Reserve a 10-byte blank space for an ID3v2 tag header.
|
||||
@ -693,7 +693,7 @@ ByteVector ID3v2::Tag::render(Version version) const
|
||||
|
||||
// Loop through the frames rendering them and adding them to the tagData.
|
||||
|
||||
for(const auto &frame : std::as_const(frameList)) {
|
||||
for(const auto &frame : std::as_const(frames)) {
|
||||
frame->header()->setVersion(version == v3 ? 3 : 4);
|
||||
if(frame->header()->frameID().size() != 4) {
|
||||
debug("An ID3v2 frame of unsupported or unknown type \'"
|
||||
|
@ -308,14 +308,16 @@ void MPEG::Header::parse(File *file, offset_t offset, bool checkLength)
|
||||
|
||||
// Samples per frame
|
||||
|
||||
static constexpr std::array samplesPerFrame {
|
||||
static constexpr std::array samplesPerFrameForLayer {
|
||||
// MPEG1, 2/2.5
|
||||
std::pair(384, 384), // Layer I
|
||||
std::pair(1152, 1152), // Layer II
|
||||
std::pair(1152, 576), // Layer III
|
||||
};
|
||||
|
||||
d->samplesPerFrame = versionIndex ? samplesPerFrame[layerIndex].second : samplesPerFrame[layerIndex].first;
|
||||
d->samplesPerFrame = versionIndex
|
||||
? samplesPerFrameForLayer[layerIndex].second
|
||||
: samplesPerFrameForLayer[layerIndex].first;
|
||||
|
||||
// Calculate the frame length
|
||||
|
||||
|
@ -165,7 +165,7 @@ void MPEG::Properties::read(File *file, ReadStyle readStyle)
|
||||
d->bitrate = static_cast<int>(d->xingHeader->totalSize() * 8.0 / length + 0.5);
|
||||
}
|
||||
else {
|
||||
int bitrate = firstHeader.bitrate();
|
||||
int bitRate = firstHeader.bitrate();
|
||||
if(firstHeader.isADTS()) {
|
||||
// ADTS is probably VBR, so to get the real length, we would have to go
|
||||
// through all frames, count the frames in numFrames and sum their
|
||||
@ -180,7 +180,7 @@ void MPEG::Properties::read(File *file, ReadStyle readStyle)
|
||||
// for 10 frames and then calculate the length from the estimated bitrate
|
||||
// and the stream length.
|
||||
if(readStyle == Fast) {
|
||||
bitrate = 0;
|
||||
bitRate = 0;
|
||||
d->length = 0;
|
||||
}
|
||||
else {
|
||||
@ -210,7 +210,7 @@ void MPEG::Properties::read(File *file, ReadStyle readStyle)
|
||||
lastBytesPerFrame = bytesPerFrame;
|
||||
}
|
||||
}
|
||||
bitrate = firstHeader.samplesPerFrame() != 0
|
||||
bitRate = firstHeader.samplesPerFrame() != 0
|
||||
? static_cast<int>((bytesPerFrame * 8 * firstHeader.sampleRate())
|
||||
/ 1000 / firstHeader.samplesPerFrame())
|
||||
: 0;
|
||||
@ -222,10 +222,10 @@ void MPEG::Properties::read(File *file, ReadStyle readStyle)
|
||||
|
||||
// TODO: Make this more robust with audio property detection for VBR without a
|
||||
// Xing header.
|
||||
bitrate = firstHeader.bitrate();
|
||||
bitRate = firstHeader.bitrate();
|
||||
}
|
||||
if(bitrate > 0) {
|
||||
d->bitrate = bitrate;
|
||||
if(bitRate > 0) {
|
||||
d->bitrate = bitRate;
|
||||
|
||||
// Look for the last MPEG audio frame to calculate the stream length.
|
||||
|
||||
|
@ -53,7 +53,6 @@ public:
|
||||
pages.setAutoDelete(true);
|
||||
}
|
||||
|
||||
unsigned int streamSerialNumber;
|
||||
List<Page *> pages;
|
||||
std::unique_ptr<PageHeader> firstPageHeader;
|
||||
std::unique_ptr<PageHeader> lastPageHeader;
|
||||
@ -148,8 +147,8 @@ bool Ogg::File::save()
|
||||
return false;
|
||||
}
|
||||
|
||||
for(const auto &[i, packet] : std::as_const(d->dirtyPackets))
|
||||
writePacket(i, packet);
|
||||
for(const auto &[i, pkt] : std::as_const(d->dirtyPackets))
|
||||
writePacket(i, pkt);
|
||||
|
||||
d->dirtyPackets.clear();
|
||||
|
||||
@ -282,10 +281,10 @@ void Ogg::File::writePacket(unsigned int i, const ByteVector &packet)
|
||||
break;
|
||||
|
||||
page.setPageSequenceNumber(page.pageSequenceNumber() + numberOfNewPages);
|
||||
const ByteVector data = page.render();
|
||||
const ByteVector pageData = page.render();
|
||||
|
||||
seek(pageOffset + 18);
|
||||
writeBlock(data.mid(18, 8));
|
||||
writeBlock(pageData.mid(18, 8));
|
||||
|
||||
if(page.header()->lastPageOfStream())
|
||||
break;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "oggpage.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <array>
|
||||
#include <utility>
|
||||
|
||||
@ -91,10 +92,10 @@ unsigned int pageChecksum(const ByteVector &data)
|
||||
0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
|
||||
};
|
||||
|
||||
unsigned int sum = 0;
|
||||
for(const auto &byte : data)
|
||||
sum = (sum << 8) ^ crcTable[((sum >> 24) & 0xff) ^ static_cast<unsigned char>(byte)];
|
||||
return sum;
|
||||
return std::accumulate(data.cbegin(), data.cend(), 0U,
|
||||
[](unsigned int sum, unsigned char byte) {
|
||||
return (sum << 8) ^ crcTable[((sum >> 24) & 0xff) ^ byte];
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@ -212,8 +213,8 @@ ByteVectorList Ogg::Page::packets() const
|
||||
d->file->seek(d->fileOffset + d->header.size());
|
||||
|
||||
const List<int> packetSizes = d->header.packetSizes();
|
||||
for(const auto &size : packetSizes)
|
||||
l.append(d->file->readBlock(size));
|
||||
for(const auto &sz : packetSizes)
|
||||
l.append(d->file->readBlock(sz));
|
||||
}
|
||||
else
|
||||
debug("Ogg::Page::packets() -- attempting to read packets from an invalid page.");
|
||||
@ -272,9 +273,10 @@ List<Ogg::Page *> Ogg::Page::paginate(const ByteVectorList &packets,
|
||||
|
||||
if(strategy != Repaginate) {
|
||||
|
||||
size_t tableSize = 0;
|
||||
for(const auto &packet : packets)
|
||||
tableSize += packet.size() / 255 + 1;
|
||||
size_t tableSize = std::accumulate(packets.cbegin(), packets.cend(), 0,
|
||||
[](size_t acc, const ByteVector &packet) {
|
||||
return acc + packet.size() / 255 + 1;
|
||||
});
|
||||
|
||||
if(tableSize > 255)
|
||||
strategy = Repaginate;
|
||||
|
@ -65,34 +65,34 @@ Ogg::XiphComment::~XiphComment() = default;
|
||||
|
||||
String Ogg::XiphComment::title() const
|
||||
{
|
||||
StringList value = d->fieldListMap.value("TITLE");
|
||||
return value.isEmpty() ? String() : joinTagValues(value);
|
||||
StringList val = d->fieldListMap.value("TITLE");
|
||||
return val.isEmpty() ? String() : joinTagValues(val);
|
||||
}
|
||||
|
||||
String Ogg::XiphComment::artist() const
|
||||
{
|
||||
StringList value = d->fieldListMap.value("ARTIST");
|
||||
return value.isEmpty() ? String() : joinTagValues(value);
|
||||
StringList val = d->fieldListMap.value("ARTIST");
|
||||
return val.isEmpty() ? String() : joinTagValues(val);
|
||||
}
|
||||
|
||||
String Ogg::XiphComment::album() const
|
||||
{
|
||||
StringList value = d->fieldListMap.value("ALBUM");
|
||||
return value.isEmpty() ? String() : joinTagValues(value);
|
||||
StringList val = d->fieldListMap.value("ALBUM");
|
||||
return val.isEmpty() ? String() : joinTagValues(val);
|
||||
}
|
||||
|
||||
String Ogg::XiphComment::comment() const
|
||||
{
|
||||
StringList value = d->fieldListMap.value("DESCRIPTION");
|
||||
if(!value.isEmpty()) {
|
||||
StringList val = d->fieldListMap.value("DESCRIPTION");
|
||||
if(!val.isEmpty()) {
|
||||
d->commentField = "DESCRIPTION";
|
||||
return joinTagValues(value);
|
||||
return joinTagValues(val);
|
||||
}
|
||||
|
||||
value = d->fieldListMap.value("COMMENT");
|
||||
if(!value.isEmpty()) {
|
||||
val = d->fieldListMap.value("COMMENT");
|
||||
if(!val.isEmpty()) {
|
||||
d->commentField = "COMMENT";
|
||||
return joinTagValues(value);
|
||||
return joinTagValues(val);
|
||||
}
|
||||
|
||||
return String();
|
||||
@ -100,29 +100,29 @@ String Ogg::XiphComment::comment() const
|
||||
|
||||
String Ogg::XiphComment::genre() const
|
||||
{
|
||||
StringList value = d->fieldListMap.value("GENRE");
|
||||
return value.isEmpty() ? String() : joinTagValues(value);
|
||||
StringList val = d->fieldListMap.value("GENRE");
|
||||
return val.isEmpty() ? String() : joinTagValues(val);
|
||||
}
|
||||
|
||||
unsigned int Ogg::XiphComment::year() const
|
||||
{
|
||||
StringList value = d->fieldListMap.value("DATE");
|
||||
if(!value.isEmpty())
|
||||
return value.front().toInt();
|
||||
value = d->fieldListMap.value("YEAR");
|
||||
if(!value.isEmpty())
|
||||
return value.front().toInt();
|
||||
StringList val = d->fieldListMap.value("DATE");
|
||||
if(!val.isEmpty())
|
||||
return val.front().toInt();
|
||||
val = d->fieldListMap.value("YEAR");
|
||||
if(!val.isEmpty())
|
||||
return val.front().toInt();
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int Ogg::XiphComment::track() const
|
||||
{
|
||||
StringList value = d->fieldListMap.value("TRACKNUMBER");
|
||||
if(!value.isEmpty())
|
||||
return value.front().toInt();
|
||||
value = d->fieldListMap.value("TRACKNUM");
|
||||
if(!value.isEmpty())
|
||||
return value.front().toInt();
|
||||
StringList val = d->fieldListMap.value("TRACKNUMBER");
|
||||
if(!val.isEmpty())
|
||||
return val.front().toInt();
|
||||
val = d->fieldListMap.value("TRACKNUM");
|
||||
if(!val.isEmpty())
|
||||
return val.front().toInt();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -246,7 +246,7 @@ StringList Ogg::XiphComment::complexPropertyKeys() const
|
||||
|
||||
List<VariantMap> Ogg::XiphComment::complexProperties(const String &key) const
|
||||
{
|
||||
List<VariantMap> properties;
|
||||
List<VariantMap> props;
|
||||
const String uppercaseKey = key.upper();
|
||||
if(uppercaseKey == "PICTURE") {
|
||||
for(const FLAC::Picture *picture : std::as_const(d->pictureList)) {
|
||||
@ -260,10 +260,10 @@ List<VariantMap> Ogg::XiphComment::complexProperties(const String &key) const
|
||||
property.insert("height", picture->height());
|
||||
property.insert("numColors", picture->numColors());
|
||||
property.insert("colorDepth", picture->colorDepth());
|
||||
properties.append(property);
|
||||
props.append(property);
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
return props;
|
||||
}
|
||||
|
||||
bool Ogg::XiphComment::setComplexProperties(const String &key, const List<VariantMap> &value)
|
||||
@ -398,10 +398,10 @@ ByteVector Ogg::XiphComment::render(bool addFramingBit) const
|
||||
|
||||
for(const auto &[fieldName, values] : std::as_const(d->fieldListMap)) {
|
||||
// And now iterate over the values of the current list.
|
||||
for(const auto &value : values) {
|
||||
for(const auto &val : values) {
|
||||
ByteVector fieldData = fieldName.data(String::UTF8);
|
||||
fieldData.append('=');
|
||||
fieldData.append(value.data(String::UTF8));
|
||||
fieldData.append(val.data(String::UTF8));
|
||||
|
||||
data.append(ByteVector::fromUInt(fieldData.size(), false));
|
||||
data.append(fieldData);
|
||||
|
@ -141,12 +141,12 @@ void RIFF::AIFF::Properties::read(File *file)
|
||||
d->sampleFrames = data.toUInt(2U);
|
||||
d->bitsPerSample = data.toShort(6U);
|
||||
|
||||
const long double sampleRate = data.toFloat80BE(8);
|
||||
if(sampleRate >= 1.0)
|
||||
d->sampleRate = static_cast<int>(sampleRate + 0.5);
|
||||
const long double smplRate = data.toFloat80BE(8);
|
||||
if(smplRate >= 1.0)
|
||||
d->sampleRate = static_cast<int>(smplRate + 0.5);
|
||||
|
||||
if(d->sampleFrames > 0 && d->sampleRate > 0) {
|
||||
const double length = d->sampleFrames * 1000.0 / sampleRate;
|
||||
const double length = d->sampleFrames * 1000.0 / smplRate;
|
||||
d->length = static_cast<int>(length + 0.5);
|
||||
d->bitrate = static_cast<int>(streamLength * 8.0 / length + 0.5);
|
||||
}
|
||||
|
@ -297,21 +297,21 @@ void RIFF::File::read()
|
||||
while(offset + 8 <= length()) {
|
||||
|
||||
seek(offset);
|
||||
const ByteVector chunkName = readBlock(4);
|
||||
const ByteVector chnkName = readBlock(4);
|
||||
const unsigned int chunkSize = readBlock(4).toUInt(bigEndian);
|
||||
|
||||
if(!isValidChunkName(chunkName)) {
|
||||
debug("RIFF::File::read() -- Chunk '" + chunkName + "' has invalid ID");
|
||||
if(!isValidChunkName(chnkName)) {
|
||||
debug("RIFF::File::read() -- Chunk '" + chnkName + "' has invalid ID");
|
||||
break;
|
||||
}
|
||||
|
||||
if(static_cast<long long>(offset) + 8 + chunkSize > length()) {
|
||||
debug("RIFF::File::read() -- Chunk '" + chunkName + "' has invalid size (larger than the file size)");
|
||||
debug("RIFF::File::read() -- Chunk '" + chnkName + "' has invalid size (larger than the file size)");
|
||||
break;
|
||||
}
|
||||
|
||||
Chunk chunk;
|
||||
chunk.name = chunkName;
|
||||
chunk.name = chnkName;
|
||||
chunk.size = chunkSize;
|
||||
chunk.offset = offset + 8;
|
||||
chunk.padding = 0;
|
||||
|
@ -199,10 +199,10 @@ namespace
|
||||
PropertyMap RIFF::Info::Tag::properties() const
|
||||
{
|
||||
PropertyMap props;
|
||||
for(const auto &[id, value] : std::as_const(d->fieldListMap)) {
|
||||
for(const auto &[id, val] : std::as_const(d->fieldListMap)) {
|
||||
String key = propertyKeyForId.value(id);
|
||||
if(!key.isEmpty()) {
|
||||
props[key].append(value);
|
||||
props[key].append(val);
|
||||
}
|
||||
else {
|
||||
props.addUnsupportedData(key);
|
||||
@ -234,13 +234,13 @@ PropertyMap RIFF::Info::Tag::setProperties(const PropertyMap &props)
|
||||
}
|
||||
|
||||
PropertyMap ignoredProps;
|
||||
for(const auto &[key, value] : props) {
|
||||
for(const auto &[key, val] : props) {
|
||||
ByteVector id = idForPropertyKey.value(key);
|
||||
if(!id.isEmpty() && !value.isEmpty()) {
|
||||
d->fieldListMap[id] = value.front();
|
||||
if(!id.isEmpty() && !val.isEmpty()) {
|
||||
d->fieldListMap[id] = val.front();
|
||||
}
|
||||
else {
|
||||
ignoredProps.insert(key, value);
|
||||
ignoredProps.insert(key, val);
|
||||
}
|
||||
}
|
||||
return ignoredProps;
|
||||
|
@ -77,43 +77,43 @@ void Tag::removeUnsupportedProperties(const StringList&)
|
||||
|
||||
PropertyMap Tag::setProperties(const PropertyMap &origProps)
|
||||
{
|
||||
PropertyMap properties(origProps);
|
||||
properties.removeEmpty();
|
||||
PropertyMap props(origProps);
|
||||
props.removeEmpty();
|
||||
StringList oneValueSet;
|
||||
// can this be simplified by using some preprocessor defines / function pointers?
|
||||
if(properties.contains("TITLE")) {
|
||||
setTitle(properties["TITLE"].front());
|
||||
if(props.contains("TITLE")) {
|
||||
setTitle(props["TITLE"].front());
|
||||
oneValueSet.append("TITLE");
|
||||
} else
|
||||
setTitle(String());
|
||||
|
||||
if(properties.contains("ARTIST")) {
|
||||
setArtist(properties["ARTIST"].front());
|
||||
if(props.contains("ARTIST")) {
|
||||
setArtist(props["ARTIST"].front());
|
||||
oneValueSet.append("ARTIST");
|
||||
} else
|
||||
setArtist(String());
|
||||
|
||||
if(properties.contains("ALBUM")) {
|
||||
setAlbum(properties["ALBUM"].front());
|
||||
if(props.contains("ALBUM")) {
|
||||
setAlbum(props["ALBUM"].front());
|
||||
oneValueSet.append("ALBUM");
|
||||
} else
|
||||
setAlbum(String());
|
||||
|
||||
if(properties.contains("COMMENT")) {
|
||||
setComment(properties["COMMENT"].front());
|
||||
if(props.contains("COMMENT")) {
|
||||
setComment(props["COMMENT"].front());
|
||||
oneValueSet.append("COMMENT");
|
||||
} else
|
||||
setComment(String());
|
||||
|
||||
if(properties.contains("GENRE")) {
|
||||
setGenre(properties["GENRE"].front());
|
||||
if(props.contains("GENRE")) {
|
||||
setGenre(props["GENRE"].front());
|
||||
oneValueSet.append("GENRE");
|
||||
} else
|
||||
setGenre(String());
|
||||
|
||||
if(properties.contains("DATE")) {
|
||||
if(props.contains("DATE")) {
|
||||
bool ok;
|
||||
int date = properties["DATE"].front().toInt(&ok);
|
||||
int date = props["DATE"].front().toInt(&ok);
|
||||
if(ok) {
|
||||
setYear(date);
|
||||
oneValueSet.append("DATE");
|
||||
@ -123,11 +123,11 @@ PropertyMap Tag::setProperties(const PropertyMap &origProps)
|
||||
else
|
||||
setYear(0);
|
||||
|
||||
if(properties.contains("TRACKNUMBER")) {
|
||||
if(props.contains("TRACKNUMBER")) {
|
||||
bool ok;
|
||||
int track = properties["TRACKNUMBER"].front().toInt(&ok);
|
||||
int trackNumber = props["TRACKNUMBER"].front().toInt(&ok);
|
||||
if(ok) {
|
||||
setTrack(track);
|
||||
setTrack(trackNumber);
|
||||
oneValueSet.append("TRACKNUMBER");
|
||||
} else
|
||||
setTrack(0);
|
||||
@ -138,12 +138,12 @@ PropertyMap Tag::setProperties(const PropertyMap &origProps)
|
||||
// for each tag that has been set above, remove the first entry in the corresponding
|
||||
// value list. The others will be returned as unsupported by this format.
|
||||
for(const auto &entry : std::as_const(oneValueSet)) {
|
||||
if(properties[entry].size() == 1)
|
||||
properties.erase(entry);
|
||||
if(props[entry].size() == 1)
|
||||
props.erase(entry);
|
||||
else
|
||||
properties[entry].erase(properties[entry].begin());
|
||||
props[entry].erase(props[entry].begin());
|
||||
}
|
||||
return properties;
|
||||
return props;
|
||||
}
|
||||
|
||||
StringList Tag::complexPropertyKeys() const
|
||||
@ -183,9 +183,9 @@ void Tag::duplicate(const Tag *source, Tag *target, bool overwrite) // static
|
||||
target->setComment(source->comment());
|
||||
if(target->genre().isEmpty())
|
||||
target->setGenre(source->genre());
|
||||
if(target->year() <= 0)
|
||||
if(target->year() == 0)
|
||||
target->setYear(source->year());
|
||||
if(target->track() <= 0)
|
||||
if(target->track() == 0)
|
||||
target->setTrack(source->track());
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ public:
|
||||
TagUnionPrivate() = default;
|
||||
~TagUnionPrivate()
|
||||
{
|
||||
for(auto &tag : tags)
|
||||
for(Tag *tag : tags)
|
||||
delete tag;
|
||||
}
|
||||
|
||||
@ -106,29 +106,26 @@ void TagUnion::set(int index, Tag *tag)
|
||||
|
||||
PropertyMap TagUnion::properties() const
|
||||
{
|
||||
for(const auto &tag : d->tags) {
|
||||
if(tag && !tag->isEmpty()) {
|
||||
return tag->properties();
|
||||
}
|
||||
}
|
||||
|
||||
return PropertyMap();
|
||||
auto it = std::find_if(d->tags.cbegin(), d->tags.cend(), [](Tag *t) {
|
||||
return t && !t->isEmpty();
|
||||
});
|
||||
return it != d->tags.cend() ? (*it)->properties() : PropertyMap();
|
||||
}
|
||||
|
||||
void TagUnion::removeUnsupportedProperties(const StringList &unsupported)
|
||||
{
|
||||
for(const auto &tag : d->tags) {
|
||||
if(tag) {
|
||||
tag->removeUnsupportedProperties(unsupported);
|
||||
for(const auto &t : d->tags) {
|
||||
if(t) {
|
||||
t->removeUnsupportedProperties(unsupported);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StringList TagUnion::complexPropertyKeys() const
|
||||
{
|
||||
for(const auto &tag : d->tags) {
|
||||
if(tag) {
|
||||
const StringList keys = tag->complexPropertyKeys();
|
||||
for(const auto &t : d->tags) {
|
||||
if(t) {
|
||||
const StringList keys = t->complexPropertyKeys();
|
||||
if(!keys.isEmpty()) {
|
||||
return keys;
|
||||
}
|
||||
@ -139,9 +136,9 @@ StringList TagUnion::complexPropertyKeys() const
|
||||
|
||||
List<VariantMap> TagUnion::complexProperties(const String &key) const
|
||||
{
|
||||
for(const auto &tag : d->tags) {
|
||||
if(tag) {
|
||||
const List<VariantMap> props = tag->complexProperties(key);
|
||||
for(const auto &t : d->tags) {
|
||||
if(t) {
|
||||
const List<VariantMap> props = t->complexProperties(key);
|
||||
if(!props.isEmpty()) {
|
||||
return props;
|
||||
}
|
||||
@ -153,9 +150,9 @@ List<VariantMap> TagUnion::complexProperties(const String &key) const
|
||||
bool TagUnion::setComplexProperties(const String &key, const List<VariantMap> &value)
|
||||
{
|
||||
bool combinedResult = false;
|
||||
for(const auto &tag : d->tags) {
|
||||
if(tag) {
|
||||
if(tag->setComplexProperties(key, value)) {
|
||||
for(const auto &t : d->tags) {
|
||||
if(t) {
|
||||
if(t->setComplexProperties(key, value)) {
|
||||
combinedResult = true;
|
||||
}
|
||||
}
|
||||
|
@ -310,9 +310,9 @@ List<T> &List<T>::operator=(const List<T> &) = default;
|
||||
template <class T>
|
||||
List<T> &List<T>::operator=(std::initializer_list<T> init)
|
||||
{
|
||||
bool autoDelete = d->autoDelete;
|
||||
bool autoDeleteEnabled = d->autoDelete;
|
||||
List(init).swap(*this);
|
||||
setAutoDelete(autoDelete);
|
||||
setAutoDelete(autoDeleteEnabled);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -51,9 +51,9 @@ PropertyMap::PropertyMap(const PropertyMap &m) :
|
||||
PropertyMap::PropertyMap(const SimplePropertyMap &m) :
|
||||
d(std::make_unique<PropertyMapPrivate>())
|
||||
{
|
||||
for(const auto &[key, value] : m) {
|
||||
for(const auto &[key, val] : m) {
|
||||
if(!key.isEmpty())
|
||||
insert(key.upper(), value);
|
||||
insert(key.upper(), val);
|
||||
else
|
||||
d->unsupported.append(key.upper());
|
||||
}
|
||||
@ -116,8 +116,8 @@ PropertyMap &PropertyMap::erase(const PropertyMap &other)
|
||||
|
||||
PropertyMap &PropertyMap::merge(const PropertyMap &other)
|
||||
{
|
||||
for(const auto &[property, value] : other)
|
||||
insert(property, value);
|
||||
for(const auto &[property, val] : other)
|
||||
insert(property, val);
|
||||
d->unsupported.append(other.d->unsupported);
|
||||
return *this;
|
||||
}
|
||||
@ -140,14 +140,14 @@ StringList &PropertyMap::operator[](const String &key)
|
||||
|
||||
bool PropertyMap::operator==(const PropertyMap &other) const
|
||||
{
|
||||
for(const auto &[property, value] : other) {
|
||||
for(const auto &[property, val] : other) {
|
||||
auto thisFind = find(property);
|
||||
if(thisFind == end() || (thisFind->second != value))
|
||||
if(thisFind == end() || (thisFind->second != val))
|
||||
return false;
|
||||
}
|
||||
for(const auto &[property, value] : *this) {
|
||||
for(const auto &[property, val] : *this) {
|
||||
auto otherFind = other.find(property);
|
||||
if(otherFind == other.end() || (otherFind->second != value))
|
||||
if(otherFind == other.end() || (otherFind->second != val))
|
||||
return false;
|
||||
}
|
||||
return d->unsupported == other.d->unsupported;
|
||||
@ -162,8 +162,8 @@ String PropertyMap::toString() const
|
||||
{
|
||||
String ret;
|
||||
|
||||
for(const auto &[property, value] : *this)
|
||||
ret += property + "=" + value.toString(", ") + "\n";
|
||||
for(const auto &[property, val] : *this)
|
||||
ret += property + "=" + val.toString(", ") + "\n";
|
||||
if(!d->unsupported.isEmpty())
|
||||
ret += "Unsupported Data: " + d->unsupported.toString(", ") + "\n";
|
||||
return ret;
|
||||
@ -172,9 +172,9 @@ String PropertyMap::toString() const
|
||||
void PropertyMap::removeEmpty()
|
||||
{
|
||||
PropertyMap m;
|
||||
for(const auto &[property, value] : std::as_const(*this)) {
|
||||
if(!value.isEmpty())
|
||||
m.insert(property, value);
|
||||
for(const auto &[property, val] : std::as_const(*this)) {
|
||||
if(!val.isEmpty())
|
||||
m.insert(property, val);
|
||||
}
|
||||
*this = m;
|
||||
}
|
||||
|
@ -482,14 +482,14 @@ ByteVector String::data(Type t) const
|
||||
|
||||
int String::toInt(bool *ok) const
|
||||
{
|
||||
const wchar_t *begin = d->data.c_str();
|
||||
wchar_t *end;
|
||||
const wchar_t *beginPtr = d->data.c_str();
|
||||
wchar_t *endPtr;
|
||||
errno = 0;
|
||||
const long value = ::wcstol(begin, &end, 10);
|
||||
const long value = ::wcstol(beginPtr, &endPtr, 10);
|
||||
|
||||
// Has wcstol() consumed the entire string and not overflowed?
|
||||
if(ok) {
|
||||
*ok = (errno == 0 && end > begin && *end == L'\0');
|
||||
*ok = (errno == 0 && endPtr > beginPtr && *endPtr == L'\0');
|
||||
*ok = (*ok && value > INT_MIN && value < INT_MAX);
|
||||
}
|
||||
|
||||
|
@ -249,10 +249,10 @@ void WavPack::Properties::read(File *file, offset_t streamLength)
|
||||
}
|
||||
|
||||
const unsigned int blockSize = data.toUInt(4, false);
|
||||
const unsigned int sampleFrames = data.toUInt(12, false);
|
||||
const unsigned int smplFrames = data.toUInt(12, false);
|
||||
const unsigned int blockSamples = data.toUInt(20, false);
|
||||
const unsigned int flags = data.toUInt(24, false);
|
||||
unsigned int sampleRate = sampleRates[(flags & SRATE_MASK) >> SRATE_LSB];
|
||||
unsigned int smplRate = sampleRates[(flags & SRATE_MASK) >> SRATE_LSB];
|
||||
|
||||
if(!blockSamples) { // ignore blocks with no samples
|
||||
offset += blockSize + 8;
|
||||
@ -267,7 +267,7 @@ void WavPack::Properties::read(File *file, offset_t streamLength)
|
||||
// For non-standard sample rates or DSD audio files, we must read and parse the block
|
||||
// to actually determine the sample rate.
|
||||
|
||||
if(!sampleRate || (flags & DSD_FLAG)) {
|
||||
if(!smplRate || (flags & DSD_FLAG)) {
|
||||
const unsigned int adjustedBlockSize = blockSize - 24;
|
||||
const ByteVector block = file->readBlock(adjustedBlockSize);
|
||||
|
||||
@ -276,11 +276,11 @@ void WavPack::Properties::read(File *file, offset_t streamLength)
|
||||
break;
|
||||
}
|
||||
|
||||
if(!sampleRate)
|
||||
sampleRate = static_cast<unsigned int>(getNonStandardRate(block));
|
||||
if(!smplRate)
|
||||
smplRate = static_cast<unsigned int>(getNonStandardRate(block));
|
||||
|
||||
if(sampleRate && (flags & DSD_FLAG))
|
||||
sampleRate <<= getDsdRateShifter(block);
|
||||
if(smplRate && (flags & DSD_FLAG))
|
||||
smplRate <<= getDsdRateShifter(block);
|
||||
}
|
||||
|
||||
if(flags & INITIAL_BLOCK) {
|
||||
@ -289,9 +289,9 @@ void WavPack::Properties::read(File *file, offset_t streamLength)
|
||||
break;
|
||||
|
||||
d->bitsPerSample = ((flags & BYTES_STORED) + 1) * 8 - ((flags & SHIFT_MASK) >> SHIFT_LSB);
|
||||
d->sampleRate = static_cast<int>(sampleRate);
|
||||
d->sampleRate = static_cast<int>(smplRate);
|
||||
d->lossless = !(flags & HYBRID_FLAG);
|
||||
d->sampleFrames = sampleFrames;
|
||||
d->sampleFrames = smplFrames;
|
||||
}
|
||||
|
||||
d->channels += (flags & MONO_FLAG) ? 1 : 2;
|
||||
@ -331,11 +331,11 @@ unsigned int WavPack::Properties::seekFinalIndex(File *file, offset_t streamLeng
|
||||
const unsigned int blockIndex = data.toUInt(16, false);
|
||||
const unsigned int blockSamples = data.toUInt(20, false);
|
||||
const unsigned int flags = data.toUInt(24, false);
|
||||
const int version = data.toShort(8, false);
|
||||
const int vers = data.toShort(8, false);
|
||||
|
||||
// try not to trigger on a spurious "wvpk" in WavPack binary block data
|
||||
|
||||
if(version < MIN_STREAM_VERS || version > MAX_STREAM_VERS || (blockSize & 1) ||
|
||||
if(vers < MIN_STREAM_VERS || vers > MAX_STREAM_VERS || (blockSize & 1) ||
|
||||
blockSize < 24 || blockSize >= 1048576 || blockSamples > 131072)
|
||||
continue;
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <numeric>
|
||||
|
||||
#include "tstringlist.h"
|
||||
#include "tdebug.h"
|
||||
@ -315,20 +316,19 @@ public:
|
||||
|
||||
unsigned int size() const override
|
||||
{
|
||||
unsigned int size = 0;
|
||||
for(const auto &reader : m_readers) {
|
||||
size += reader->size();
|
||||
}
|
||||
return size;
|
||||
return std::accumulate(m_readers.cbegin(), m_readers.cend(), 0U,
|
||||
[](unsigned int acc, const auto &rdr) {
|
||||
return acc + rdr->size();
|
||||
});
|
||||
}
|
||||
|
||||
unsigned int read(TagLib::File &file, unsigned int limit) override
|
||||
{
|
||||
unsigned int sumcount = 0;
|
||||
for(const auto &reader : std::as_const(m_readers)) {
|
||||
for(const auto &rdr : std::as_const(m_readers)) {
|
||||
if(limit == 0)
|
||||
break;
|
||||
unsigned int count = reader->read(file, limit);
|
||||
unsigned int count = rdr->read(file, limit);
|
||||
limit -= count;
|
||||
sumcount += count;
|
||||
}
|
||||
@ -474,11 +474,11 @@ bool XM::File::save()
|
||||
|
||||
if(sampleHeaderSize > 18U) {
|
||||
seek(pos + 18);
|
||||
const unsigned int len = std::min(sampleHeaderSize - 18U, 22UL);
|
||||
const unsigned int sz = std::min(sampleHeaderSize - 18U, 22UL);
|
||||
if(sampleNameIndex >= lines.size())
|
||||
writeString(String(), len);
|
||||
writeString(String(), sz);
|
||||
else
|
||||
writeString(lines[sampleNameIndex ++], len);
|
||||
writeString(lines[sampleNameIndex ++], sz);
|
||||
}
|
||||
}
|
||||
pos += sampleHeaderSize;
|
||||
@ -555,11 +555,11 @@ void XM::File::read(bool)
|
||||
StructReader pattern;
|
||||
pattern.byte(packingType).u16L(rowCount).u16L(dataSize);
|
||||
|
||||
unsigned int count = pattern.read(*this, patternHeaderLength - 4U);
|
||||
READ_ASSERT(count == std::min(patternHeaderLength - 4U,
|
||||
unsigned int ptCnt = pattern.read(*this, patternHeaderLength - 4U);
|
||||
READ_ASSERT(ptCnt == std::min(patternHeaderLength - 4U,
|
||||
static_cast<unsigned long>(pattern.size())));
|
||||
|
||||
seek(patternHeaderLength - (4 + count) + dataSize, Current);
|
||||
seek(patternHeaderLength - (4 + ptCnt) + dataSize, Current);
|
||||
}
|
||||
|
||||
StringList instrumentNames;
|
||||
@ -579,8 +579,8 @@ void XM::File::read(bool)
|
||||
instrument.string(instrumentName, 22).byte(instrumentType).u16L(sampleCount);
|
||||
|
||||
// 4 for instrumentHeaderSize
|
||||
unsigned int count = 4 + instrument.read(*this, instrumentHeaderSize - 4U);
|
||||
READ_ASSERT(count == std::min(instrumentHeaderSize,
|
||||
unsigned int inCnt = 4 + instrument.read(*this, instrumentHeaderSize - 4U);
|
||||
READ_ASSERT(inCnt == std::min(instrumentHeaderSize,
|
||||
static_cast<unsigned long>(instrument.size() + 4)));
|
||||
|
||||
offset_t offset = 0;
|
||||
@ -588,9 +588,9 @@ void XM::File::read(bool)
|
||||
unsigned long sampleHeaderSize = 0;
|
||||
sumSampleCount += sampleCount;
|
||||
// wouldn't know which header size to assume otherwise:
|
||||
READ_ASSERT(instrumentHeaderSize >= count + 4 && readU32L(sampleHeaderSize));
|
||||
READ_ASSERT(instrumentHeaderSize >= inCnt + 4 && readU32L(sampleHeaderSize));
|
||||
// skip unhandled header proportion:
|
||||
seek(instrumentHeaderSize - count - 4, Current);
|
||||
seek(instrumentHeaderSize - inCnt - 4, Current);
|
||||
|
||||
for(unsigned short j = 0; j < sampleCount; ++ j) {
|
||||
unsigned long sampleLength = 0;
|
||||
@ -615,18 +615,18 @@ void XM::File::read(bool)
|
||||
.byte(compression)
|
||||
.string(sampleName, 22);
|
||||
|
||||
unsigned int count = sample.read(*this, sampleHeaderSize);
|
||||
READ_ASSERT(count == std::min(sampleHeaderSize,
|
||||
unsigned int smCnt = sample.read(*this, sampleHeaderSize);
|
||||
READ_ASSERT(smCnt == std::min(sampleHeaderSize,
|
||||
static_cast<unsigned long>(sample.size())));
|
||||
// skip unhandled header proportion:
|
||||
seek(sampleHeaderSize - count, Current);
|
||||
seek(sampleHeaderSize - smCnt, Current);
|
||||
|
||||
offset += sampleLength;
|
||||
sampleNames.append(sampleName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
offset = instrumentHeaderSize - count;
|
||||
offset = instrumentHeaderSize - inCnt;
|
||||
}
|
||||
instrumentNames.append(instrumentName);
|
||||
seek(offset, Current);
|
||||
|
@ -74,9 +74,8 @@ namespace
|
||||
}
|
||||
|
||||
private:
|
||||
CustomFrame(const ByteVector &data, Header *h) : Frame(h) {
|
||||
parseFields(fieldData(data));
|
||||
}
|
||||
CustomFrame(const ByteVector &data, Header *h)
|
||||
: Frame(h), m_value(fieldData(data).toUInt()) {}
|
||||
unsigned int m_value;
|
||||
};
|
||||
|
||||
|
@ -79,7 +79,7 @@ public:
|
||||
testRead(copy.fileName().c_str(), titleAfter, commentAfter);
|
||||
CPPUNIT_ASSERT(fileEqual(
|
||||
copy.fileName(),
|
||||
TEST_FILE_PATH_C("changed.mod")));
|
||||
testFilePath("changed.mod")));
|
||||
}
|
||||
|
||||
void testPropertyInterface()
|
||||
|
@ -714,7 +714,7 @@ public:
|
||||
CPPUNIT_ASSERT(f.tag()->isEmpty());
|
||||
CPPUNIT_ASSERT(fileEqual(
|
||||
copy.fileName(),
|
||||
TEST_FILE_PATH_C("no-tags.m4a")));
|
||||
testFilePath("no-tags.m4a")));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ public:
|
||||
testRead(copy.fileName().c_str(), titleAfter, commentAfter);
|
||||
CPPUNIT_ASSERT(fileEqual(
|
||||
copy.fileName(),
|
||||
TEST_FILE_PATH_C("changed.s3m")));
|
||||
testFilePath("changed.s3m")));
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -108,6 +108,7 @@ public:
|
||||
taglib_property_set_append(file, "COMPOSER", "Composer 2");
|
||||
taglib_property_set(file, "ALBUMARTIST", "Album Artist");
|
||||
|
||||
// cppcheck-suppress cstyleCast
|
||||
TAGLIB_COMPLEX_PROPERTY_PICTURE(props, "JPEG Data", 9, "Written by TagLib",
|
||||
"image/jpeg", "Front Cover");
|
||||
taglib_complex_property_set(file, "PICTURE", props);
|
||||
|
@ -216,7 +216,7 @@ private:
|
||||
commentAfter, trackerNameAfter);
|
||||
CPPUNIT_ASSERT(fileEqual(
|
||||
copy.fileName(),
|
||||
TEST_FILE_PATH_C("changed.xm")));
|
||||
testFilePath("changed.xm")));
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user