mirror of
https://github.com/taglib/taglib.git
synced 2026-04-08 23:22:44 -04:00
manual range loop conversions (#1126)
* manual range loop conversions Signed-off-by: Rosen Penev <rosenp@gmail.com> * Restore const containers where non const temporaries are iterated * Use std::as_const() instead of const container copies where possible --------- Signed-off-by: Rosen Penev <rosenp@gmail.com> Co-authored-by: Urs Fleisch <ufleisch@users.sourceforge.net>
This commit is contained in:
@ -28,6 +28,8 @@
|
||||
#include "tbytevectorlist.h"
|
||||
#include "tdebug.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace APE;
|
||||
|
||||
@ -174,12 +176,9 @@ int APE::Item::size() const
|
||||
switch(d->type) {
|
||||
case Text:
|
||||
if(!d->text.isEmpty()) {
|
||||
auto it = d->text.cbegin();
|
||||
|
||||
result += it->data(String::UTF8).size();
|
||||
it++;
|
||||
for(; it != d->text.cend(); ++it)
|
||||
result += 1 + it->data(String::UTF8).size();
|
||||
for(const auto &t : std::as_const(d->text))
|
||||
result += 1 + t.data(String::UTF8).size();
|
||||
result -= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -264,8 +263,7 @@ ByteVector APE::Item::render() const
|
||||
auto it = d->text.cbegin();
|
||||
|
||||
value.append(it->data(String::UTF8));
|
||||
it++;
|
||||
for(; it != d->text.cend(); ++it) {
|
||||
for(it = std::next(it); it != d->text.cend(); ++it) {
|
||||
value.append('\0');
|
||||
value.append(it->data(String::UTF8));
|
||||
}
|
||||
|
||||
@ -44,6 +44,7 @@
|
||||
#include "apeitem.h"
|
||||
|
||||
#include <array>
|
||||
#include <utility>
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace APE;
|
||||
@ -200,13 +201,12 @@ namespace
|
||||
PropertyMap APE::Tag::properties() const
|
||||
{
|
||||
PropertyMap properties;
|
||||
const auto &items = itemListMap();
|
||||
for(auto it = items.begin(); it != items.end(); ++it) {
|
||||
String tagName = it->first.upper();
|
||||
for(const auto &[tag, item] : std::as_const(itemListMap())) {
|
||||
String tagName = tag.upper();
|
||||
// if the item is Binary or Locator, or if the key is an invalid string,
|
||||
// add to unsupportedData
|
||||
if(it->second.type() != Item::Text || tagName.isEmpty()) {
|
||||
properties.unsupportedData().append(it->first);
|
||||
if(item.type() != Item::Text || tagName.isEmpty()) {
|
||||
properties.unsupportedData().append(tag);
|
||||
}
|
||||
else {
|
||||
// Some tags need to be handled specially
|
||||
@ -214,7 +214,7 @@ PropertyMap APE::Tag::properties() const
|
||||
if(tagName == t)
|
||||
tagName = k;
|
||||
}
|
||||
properties[tagName].append(it->second.toStringList());
|
||||
properties[tagName].append(item.toStringList());
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
@ -222,8 +222,8 @@ PropertyMap APE::Tag::properties() const
|
||||
|
||||
void APE::Tag::removeUnsupportedProperties(const StringList &properties)
|
||||
{
|
||||
for(auto it = properties.begin(); it != properties.end(); ++it)
|
||||
removeItem(*it);
|
||||
for(const auto &property : properties)
|
||||
removeItem(property);
|
||||
}
|
||||
|
||||
PropertyMap APE::Tag::setProperties(const PropertyMap &origProps)
|
||||
@ -239,32 +239,28 @@ PropertyMap APE::Tag::setProperties(const PropertyMap &origProps)
|
||||
|
||||
// first check if tags need to be removed completely
|
||||
StringList toRemove;
|
||||
const auto &items = itemListMap();
|
||||
for(auto remIt = items.begin(); remIt != items.end(); ++remIt) {
|
||||
String key = remIt->first.upper();
|
||||
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() && remIt->second.type() == APE::Item::Text && !properties.contains(key))
|
||||
toRemove.append(remIt->first);
|
||||
if(!key.isEmpty() && t.type() == APE::Item::Text && !properties.contains(key))
|
||||
toRemove.append(k);
|
||||
}
|
||||
|
||||
for(auto removeIt = toRemove.cbegin(); removeIt != toRemove.cend(); removeIt++)
|
||||
removeItem(*removeIt);
|
||||
for(const auto &item : std::as_const(toRemove))
|
||||
removeItem(item);
|
||||
|
||||
// now sync in the "forward direction"
|
||||
PropertyMap invalid;
|
||||
for(auto it = properties.begin(); it != properties.cend(); ++it) {
|
||||
const String &tagName = it->first;
|
||||
for(const auto &[tagName, value] : std::as_const(properties)) {
|
||||
if(!checkKey(tagName))
|
||||
invalid.insert(it->first, it->second);
|
||||
else if(!(itemListMap().contains(tagName)) || !(itemListMap()[tagName].values() == it->second)) {
|
||||
if(it->second.isEmpty())
|
||||
invalid.insert(tagName, value);
|
||||
else if(!(itemListMap().contains(tagName)) || !(itemListMap()[tagName].values() == value)) {
|
||||
if(value.isEmpty())
|
||||
removeItem(tagName);
|
||||
else {
|
||||
auto valueIt = it->second.begin();
|
||||
addValue(tagName, *valueIt, true);
|
||||
++valueIt;
|
||||
for(; valueIt != it->second.end(); ++valueIt)
|
||||
addValue(tagName, *valueIt, false);
|
||||
addValue(tagName, *value.begin(), true);
|
||||
for(auto it = std::next(value.begin()); it != value.end(); ++it)
|
||||
addValue(tagName, *it, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -363,8 +359,8 @@ ByteVector APE::Tag::render() const
|
||||
ByteVector data;
|
||||
unsigned int itemCount = 0;
|
||||
|
||||
for(auto it = d->itemListMap.cbegin(); it != d->itemListMap.cend(); ++it) {
|
||||
data.append(it->second.render());
|
||||
for(const auto &[_, list] : std::as_const(d->itemListMap)) {
|
||||
data.append(list.render());
|
||||
itemCount++;
|
||||
}
|
||||
|
||||
|
||||
@ -35,6 +35,8 @@
|
||||
#include "asfproperties.h"
|
||||
#include "asfutils.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class ASF::File::FilePrivate
|
||||
@ -405,8 +407,8 @@ void ASF::File::FilePrivate::HeaderExtensionObject::parse(ASF::File *file, unsig
|
||||
ByteVector ASF::File::FilePrivate::HeaderExtensionObject::render(ASF::File *file)
|
||||
{
|
||||
data.clear();
|
||||
for(auto it = objects.cbegin(); it != objects.cend(); ++it) {
|
||||
data.append((*it)->render(file));
|
||||
for(const auto &object : std::as_const(objects)) {
|
||||
data.append(object->render(file));
|
||||
}
|
||||
data = ByteVector("\x11\xD2\xD3\xAB\xBA\xA9\xcf\x11\x8E\xE6\x00\xC0\x0C\x20\x53\x65\x06\x00", 18) + ByteVector::fromUInt(data.size(), false) + data;
|
||||
return BaseObject::render(file);
|
||||
@ -563,19 +565,11 @@ bool ASF::File::save()
|
||||
d->metadataObject->attributeData.clear();
|
||||
d->metadataLibraryObject->attributeData.clear();
|
||||
|
||||
const AttributeListMap allAttributes = d->tag->attributeListMap();
|
||||
|
||||
for(auto it = allAttributes.begin(); it != allAttributes.end(); ++it) {
|
||||
|
||||
const String &name = it->first;
|
||||
const AttributeList &attributes = it->second;
|
||||
|
||||
for(const auto &[name, attributes] : std::as_const(d->tag->attributeListMap())) {
|
||||
bool inExtendedContentDescriptionObject = false;
|
||||
bool inMetadataObject = false;
|
||||
|
||||
for(auto jt = attributes.begin(); jt != attributes.end(); ++jt) {
|
||||
|
||||
const Attribute &attribute = *jt;
|
||||
for(const auto &attribute : attributes) {
|
||||
const bool largeValue = (attribute.dataSize() > 65535);
|
||||
const bool guid = (attribute.type() == Attribute::GuidType);
|
||||
|
||||
@ -594,8 +588,8 @@ bool ASF::File::save()
|
||||
}
|
||||
|
||||
ByteVector data;
|
||||
for(auto it = d->objects.cbegin(); it != d->objects.cend(); ++it) {
|
||||
data.append((*it)->render(this));
|
||||
for(const auto &object : std::as_const(d->objects)) {
|
||||
data.append(object->render(this));
|
||||
}
|
||||
|
||||
seek(16);
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "tpropertymap.h"
|
||||
|
||||
#include <array>
|
||||
#include <utility>
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
@ -285,23 +286,23 @@ PropertyMap ASF::Tag::properties() const
|
||||
props["COMMENT"] = d->comment;
|
||||
}
|
||||
|
||||
for(auto it = d->attributeListMap.cbegin(); it != d->attributeListMap.cend(); ++it) {
|
||||
const String key = translateKey(it->first);
|
||||
for(const auto &[k, attributes] : std::as_const(d->attributeListMap)) {
|
||||
const String key = translateKey(k);
|
||||
if(!key.isEmpty()) {
|
||||
for(auto it2 = it->second.begin(); it2 != it->second.end(); ++it2) {
|
||||
for(const auto &attribute : attributes) {
|
||||
if(key == "TRACKNUMBER") {
|
||||
if(it2->type() == ASF::Attribute::DWordType)
|
||||
props.insert(key, String::number(it2->toUInt()));
|
||||
if(attribute.type() == ASF::Attribute::DWordType)
|
||||
props.insert(key, String::number(attribute.toUInt()));
|
||||
else
|
||||
props.insert(key, it2->toString());
|
||||
props.insert(key, attribute.toString());
|
||||
}
|
||||
else {
|
||||
props.insert(key, it2->toString());
|
||||
props.insert(key, attribute.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
props.unsupportedData().append(it->first);
|
||||
props.unsupportedData().append(k);
|
||||
}
|
||||
}
|
||||
return props;
|
||||
@ -309,8 +310,8 @@ PropertyMap ASF::Tag::properties() const
|
||||
|
||||
void ASF::Tag::removeUnsupportedProperties(const StringList &props)
|
||||
{
|
||||
for(auto it = props.begin(); it != props.end(); ++it)
|
||||
d->attributeListMap.erase(*it);
|
||||
for(const auto &prop : props)
|
||||
d->attributeListMap.erase(prop);
|
||||
}
|
||||
|
||||
PropertyMap ASF::Tag::setProperties(const PropertyMap &props)
|
||||
@ -323,51 +324,49 @@ PropertyMap ASF::Tag::setProperties(const PropertyMap &props)
|
||||
}
|
||||
|
||||
const PropertyMap origProps = properties();
|
||||
auto it = origProps.begin();
|
||||
for(; it != origProps.end(); ++it) {
|
||||
if(!props.contains(it->first) || props[it->first].isEmpty()) {
|
||||
if(it->first == "TITLE") {
|
||||
for(const auto &[prop, _] : origProps) {
|
||||
if(!props.contains(prop) || props[prop].isEmpty()) {
|
||||
if(prop == "TITLE") {
|
||||
d->title.clear();
|
||||
}
|
||||
else if(it->first == "ARTIST") {
|
||||
else if(prop == "ARTIST") {
|
||||
d->artist.clear();
|
||||
}
|
||||
else if(it->first == "COMMENT") {
|
||||
else if(prop == "COMMENT") {
|
||||
d->comment.clear();
|
||||
}
|
||||
else if(it->first == "COPYRIGHT") {
|
||||
else if(prop == "COPYRIGHT") {
|
||||
d->copyright.clear();
|
||||
}
|
||||
else {
|
||||
d->attributeListMap.erase(reverseKeyMap[it->first]);
|
||||
d->attributeListMap.erase(reverseKeyMap[prop]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PropertyMap ignoredProps;
|
||||
it = props.begin();
|
||||
for(; it != props.end(); ++it) {
|
||||
if(reverseKeyMap.contains(it->first)) {
|
||||
String name = reverseKeyMap[it->first];
|
||||
for(const auto &[prop, attributes] : props) {
|
||||
if(reverseKeyMap.contains(prop)) {
|
||||
String name = reverseKeyMap[prop];
|
||||
removeItem(name);
|
||||
for(auto it2 = it->second.begin(); it2 != it->second.end(); ++it2) {
|
||||
addAttribute(name, *it2);
|
||||
for(const auto &attribute : attributes) {
|
||||
addAttribute(name, attribute);
|
||||
}
|
||||
}
|
||||
else if(it->first == "TITLE") {
|
||||
d->title = it->second.toString();
|
||||
else if(prop == "TITLE") {
|
||||
d->title = attributes.toString();
|
||||
}
|
||||
else if(it->first == "ARTIST") {
|
||||
d->artist = it->second.toString();
|
||||
else if(prop == "ARTIST") {
|
||||
d->artist = attributes.toString();
|
||||
}
|
||||
else if(it->first == "COMMENT") {
|
||||
d->comment = it->second.toString();
|
||||
else if(prop == "COMMENT") {
|
||||
d->comment = attributes.toString();
|
||||
}
|
||||
else if(it->first == "COPYRIGHT") {
|
||||
d->copyright = it->second.toString();
|
||||
else if(prop == "COPYRIGHT") {
|
||||
d->copyright = attributes.toString();
|
||||
}
|
||||
else {
|
||||
ignoredProps.insert(it->first, it->second);
|
||||
ignoredProps.insert(prop, attributes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#include "fileref.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
|
||||
#include "tdebug.h"
|
||||
#include "tfile.h"
|
||||
@ -82,8 +83,8 @@ namespace
|
||||
if(::strlen(fileName) == 0)
|
||||
return nullptr;
|
||||
#endif
|
||||
for(auto it = fileTypeResolvers.cbegin(); it != fileTypeResolvers.cend(); ++it) {
|
||||
File *file = (*it)->createFile(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
for(const auto &resolver : std::as_const(fileTypeResolvers)) {
|
||||
File *file = resolver->createFile(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(file)
|
||||
return file;
|
||||
}
|
||||
@ -94,8 +95,8 @@ namespace
|
||||
File *detectByResolvers(IOStream* stream, bool readAudioProperties,
|
||||
AudioProperties::ReadStyle audioPropertiesStyle)
|
||||
{
|
||||
for(auto it = fileTypeResolvers.cbegin(); it != fileTypeResolvers.cend(); ++it) {
|
||||
if(auto streamResolver = dynamic_cast<const FileRef::StreamTypeResolver*>(*it)) {
|
||||
for(const auto &resolver : std::as_const(fileTypeResolvers)) {
|
||||
if(auto streamResolver = dynamic_cast<const FileRef::StreamTypeResolver *>(resolver)) {
|
||||
if(File *file = streamResolver->createFileFromStream(
|
||||
stream, readAudioProperties, audioPropertiesStyle))
|
||||
return file;
|
||||
|
||||
@ -42,6 +42,8 @@
|
||||
#include "flacmetadatablock.h"
|
||||
#include "flacunknownmetadatablock.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
namespace
|
||||
@ -203,10 +205,10 @@ bool FLAC::File::save()
|
||||
// Render data for the metadata blocks
|
||||
|
||||
ByteVector data;
|
||||
for(auto it = d->blocks.cbegin(); it != d->blocks.cend(); ++it) {
|
||||
ByteVector blockData = (*it)->render();
|
||||
for(const auto &block : std::as_const(d->blocks)) {
|
||||
ByteVector blockData = block->render();
|
||||
ByteVector blockHeader = ByteVector::fromUInt(blockData.size());
|
||||
blockHeader[0] = (*it)->code();
|
||||
blockHeader[0] = block->code();
|
||||
data.append(blockHeader);
|
||||
data.append(blockData);
|
||||
}
|
||||
@ -327,9 +329,8 @@ Ogg::XiphComment *FLAC::File::xiphComment(bool create)
|
||||
List<FLAC::Picture *> FLAC::File::pictureList()
|
||||
{
|
||||
List<Picture *> pictures;
|
||||
for(auto it = d->blocks.cbegin(); it != d->blocks.cend(); ++it) {
|
||||
auto picture = dynamic_cast<Picture *>(*it);
|
||||
if(picture) {
|
||||
for(const auto &block : std::as_const(d->blocks)) {
|
||||
if(auto picture = dynamic_cast<Picture *>(block)) {
|
||||
pictures.append(picture);
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +28,8 @@
|
||||
#include "tstringlist.h"
|
||||
#include "tpropertymap.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace Mod;
|
||||
|
||||
@ -156,11 +158,11 @@ 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(auto it = oneValueSet.cbegin(); it != oneValueSet.cend(); ++it) {
|
||||
if(properties[*it].size() == 1)
|
||||
properties.erase(*it);
|
||||
for(const auto &entry : std::as_const(oneValueSet)) {
|
||||
if(properties[entry].size() == 1)
|
||||
properties.erase(entry);
|
||||
else
|
||||
properties[*it].erase( properties[*it].begin() );
|
||||
properties[entry].erase(properties[entry].begin());
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include "mp4atom.h"
|
||||
|
||||
#include <climits>
|
||||
#include <utility>
|
||||
|
||||
#include "tdebug.h"
|
||||
#include "tstring.h"
|
||||
@ -131,9 +132,9 @@ MP4::Atom::find(const char *name1, const char *name2, const char *name3, const c
|
||||
if(name1 == nullptr) {
|
||||
return this;
|
||||
}
|
||||
for(auto it = children.cbegin(); it != children.cend(); ++it) {
|
||||
if((*it)->name == name1) {
|
||||
return (*it)->find(name2, name3, name4);
|
||||
for(const auto &child : std::as_const(children)) {
|
||||
if(child->name == name1) {
|
||||
return child->find(name2, name3, name4);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
@ -143,12 +144,12 @@ MP4::AtomList
|
||||
MP4::Atom::findall(const char *name, bool recursive)
|
||||
{
|
||||
MP4::AtomList result;
|
||||
for(auto it = children.cbegin(); it != children.cend(); ++it) {
|
||||
if((*it)->name == name) {
|
||||
result.append(*it);
|
||||
for(const auto &child : std::as_const(children)) {
|
||||
if(child->name == name) {
|
||||
result.append(child);
|
||||
}
|
||||
if(recursive) {
|
||||
result.append((*it)->findall(name, recursive));
|
||||
result.append(child->findall(name, recursive));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@ -161,9 +162,9 @@ MP4::Atom::path(MP4::AtomList &path, const char *name1, const char *name2, const
|
||||
if(name1 == nullptr) {
|
||||
return true;
|
||||
}
|
||||
for(auto it = children.cbegin(); it != children.cend(); ++it) {
|
||||
if((*it)->name == name1) {
|
||||
return (*it)->path(path, name2, name3);
|
||||
for(const auto &child : std::as_const(children)) {
|
||||
if(child->name == name1) {
|
||||
return child->path(path, name2, name3);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -189,9 +190,9 @@ MP4::Atoms::~Atoms() = default;
|
||||
MP4::Atom *
|
||||
MP4::Atoms::find(const char *name1, const char *name2, const char *name3, const char *name4)
|
||||
{
|
||||
for(auto it = atoms.cbegin(); it != atoms.cend(); ++it) {
|
||||
if((*it)->name == name1) {
|
||||
return (*it)->find(name2, name3, name4);
|
||||
for(const auto &atom : std::as_const(atoms)) {
|
||||
if(atom->name == name1) {
|
||||
return atom->find(name2, name3, name4);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
@ -201,9 +202,9 @@ MP4::AtomList
|
||||
MP4::Atoms::path(const char *name1, const char *name2, const char *name3, const char *name4)
|
||||
{
|
||||
MP4::AtomList path;
|
||||
for(auto it = atoms.cbegin(); it != atoms.cend(); ++it) {
|
||||
if((*it)->name == name1) {
|
||||
if(!(*it)->path(path, name2, name3, name4)) {
|
||||
for(const auto &atom : std::as_const(atoms)) {
|
||||
if(atom->name == name1) {
|
||||
if(!atom->path(path, name2, name3, name4)) {
|
||||
path.clear();
|
||||
}
|
||||
return path;
|
||||
|
||||
@ -37,15 +37,15 @@ namespace
|
||||
long long calculateMdatLength(const MP4::AtomList &list)
|
||||
{
|
||||
long long totalLength = 0;
|
||||
for(auto it = list.begin(); it != list.end(); ++it) {
|
||||
offset_t length = (*it)->length;
|
||||
for(const auto &atom : list) {
|
||||
offset_t length = atom->length;
|
||||
if(length == 0)
|
||||
return 0; // for safety, see checkValid() in mp4file.cpp
|
||||
|
||||
if((*it)->name == "mdat")
|
||||
if(atom->name == "mdat")
|
||||
totalLength += length;
|
||||
|
||||
totalLength += calculateMdatLength((*it)->children);
|
||||
totalLength += calculateMdatLength(atom->children);
|
||||
}
|
||||
|
||||
return totalLength;
|
||||
@ -136,13 +136,13 @@ MP4::Properties::read(File *file, Atoms *atoms)
|
||||
ByteVector data;
|
||||
|
||||
const MP4::AtomList trakList = moov->findall("trak");
|
||||
for(auto it = trakList.begin(); it != trakList.end(); ++it) {
|
||||
trak = *it;
|
||||
MP4::Atom *hdlr = trak->find("mdia", "hdlr");
|
||||
for(const auto &track : trakList) {
|
||||
MP4::Atom *hdlr = track->find("mdia", "hdlr");
|
||||
if(!hdlr) {
|
||||
debug("MP4: Atom 'trak.mdia.hdlr' not found");
|
||||
return;
|
||||
}
|
||||
trak = track;
|
||||
file->seek(hdlr->offset);
|
||||
data = file->readBlock(hdlr->length);
|
||||
if(data.containsAt("soun", 16)) {
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#include "id3v1genres.h"
|
||||
|
||||
#include <array>
|
||||
#include <utility>
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
@ -59,8 +60,7 @@ MP4::Tag::Tag(TagLib::File *file, MP4::Atoms *atoms) :
|
||||
return;
|
||||
}
|
||||
|
||||
for(auto it = ilst->children.cbegin(); it != ilst->children.cend(); ++it) {
|
||||
MP4::Atom *atom = *it;
|
||||
for(const auto &atom : std::as_const(ilst->children)) {
|
||||
file->seek(atom->offset + 8);
|
||||
if(atom->name == "----") {
|
||||
parseFreeForm(atom);
|
||||
@ -161,8 +161,8 @@ MP4::Tag::parseData(const MP4::Atom *atom, int expectedFlags, bool freeForm)
|
||||
{
|
||||
const AtomDataList data = parseData2(atom, expectedFlags, freeForm);
|
||||
ByteVectorList result;
|
||||
for(auto it = data.begin(); it != data.end(); ++it) {
|
||||
result.append(it->data);
|
||||
for(const auto &atom : data) {
|
||||
result.append(atom.data);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -242,8 +242,8 @@ MP4::Tag::parseText(const MP4::Atom *atom, int expectedFlags)
|
||||
const ByteVectorList data = parseData(atom, expectedFlags);
|
||||
if(!data.isEmpty()) {
|
||||
StringList value;
|
||||
for(auto it = data.begin(); it != data.end(); ++it) {
|
||||
value.append(String(*it, String::UTF8));
|
||||
for(const auto &byte : data) {
|
||||
value.append(String(byte, String::UTF8));
|
||||
}
|
||||
addItem(atom->name, value);
|
||||
}
|
||||
@ -342,8 +342,8 @@ ByteVector
|
||||
MP4::Tag::renderData(const ByteVector &name, int flags, const ByteVectorList &data) const
|
||||
{
|
||||
ByteVector result;
|
||||
for(auto it = data.begin(); it != data.end(); ++it) {
|
||||
result.append(renderAtom("data", ByteVector::fromUInt(flags) + ByteVector(4, '\0') + *it));
|
||||
for(const auto &byte : data) {
|
||||
result.append(renderAtom("data", ByteVector::fromUInt(flags) + ByteVector(4, '\0') + byte));
|
||||
}
|
||||
return renderAtom(name, result);
|
||||
}
|
||||
@ -413,9 +413,9 @@ ByteVector
|
||||
MP4::Tag::renderText(const ByteVector &name, const MP4::Item &item, int flags) const
|
||||
{
|
||||
ByteVectorList data;
|
||||
const StringList value = item.toStringList();
|
||||
for(auto it = value.begin(); it != value.end(); ++it) {
|
||||
data.append(it->data(String::UTF8));
|
||||
const StringList values = item.toStringList();
|
||||
for(const auto &value : values) {
|
||||
data.append(value.data(String::UTF8));
|
||||
}
|
||||
return renderData(name, flags, data);
|
||||
}
|
||||
@ -424,10 +424,10 @@ ByteVector
|
||||
MP4::Tag::renderCovr(const ByteVector &name, const MP4::Item &item) const
|
||||
{
|
||||
ByteVector data;
|
||||
const MP4::CoverArtList value = item.toCoverArtList();
|
||||
for(auto it = value.begin(); it != value.end(); ++it) {
|
||||
data.append(renderAtom("data", ByteVector::fromUInt(it->format()) +
|
||||
ByteVector(4, '\0') + it->data()));
|
||||
const MP4::CoverArtList values = item.toCoverArtList();
|
||||
for(const auto &value : values) {
|
||||
data.append(renderAtom("data", ByteVector::fromUInt(value.format()) +
|
||||
ByteVector(4, '\0') + value.data()));
|
||||
}
|
||||
return renderAtom(name, data);
|
||||
}
|
||||
@ -453,15 +453,17 @@ MP4::Tag::renderFreeForm(const String &name, const MP4::Item &item) const
|
||||
}
|
||||
}
|
||||
if(type == TypeUTF8) {
|
||||
const StringList value = item.toStringList();
|
||||
for(auto it = value.begin(); it != value.end(); ++it) {
|
||||
data.append(renderAtom("data", ByteVector::fromUInt(type) + ByteVector(4, '\0') + it->data(String::UTF8)));
|
||||
const StringList values = item.toStringList();
|
||||
for(const auto &value : values) {
|
||||
data.append(renderAtom("data", ByteVector::fromUInt(type) +
|
||||
ByteVector(4, '\0') + value.data(String::UTF8)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
const ByteVectorList value = item.toByteVectorList();
|
||||
for(auto it = value.begin(); it != value.end(); ++it) {
|
||||
data.append(renderAtom("data", ByteVector::fromUInt(type) + ByteVector(4, '\0') + *it));
|
||||
const ByteVectorList values = item.toByteVectorList();
|
||||
for(const auto &value : values) {
|
||||
data.append(renderAtom("data", ByteVector::fromUInt(type) +
|
||||
ByteVector(4, '\0') + value));
|
||||
}
|
||||
}
|
||||
return renderAtom("----", data);
|
||||
@ -471,26 +473,24 @@ bool
|
||||
MP4::Tag::save()
|
||||
{
|
||||
ByteVector data;
|
||||
for(auto it = d->items.cbegin(); it != d->items.cend(); ++it) {
|
||||
const String name = it->first;
|
||||
for(const auto &[name, item] : std::as_const(d->items)) {
|
||||
if(name.startsWith("----")) {
|
||||
data.append(renderFreeForm(name, it->second));
|
||||
data.append(renderFreeForm(name, item));
|
||||
}
|
||||
else if(name == "trkn") {
|
||||
data.append(renderIntPair(name.data(String::Latin1), it->second));
|
||||
data.append(renderIntPair(name.data(String::Latin1), item));
|
||||
}
|
||||
else if(name == "disk") {
|
||||
data.append(renderIntPairNoTrailing(name.data(String::Latin1), it->second));
|
||||
data.append(renderIntPairNoTrailing(name.data(String::Latin1), item));
|
||||
}
|
||||
else if(name == "cpil" || name == "pgap" || name == "pcst" || name == "hdvd" ||
|
||||
name == "shwm") {
|
||||
data.append(renderBool(name.data(String::Latin1), it->second));
|
||||
data.append(renderBool(name.data(String::Latin1), item));
|
||||
}
|
||||
else if(name == "tmpo" || name == "\251mvi" || name == "\251mvc") {
|
||||
data.append(renderInt(name.data(String::Latin1), it->second));
|
||||
data.append(renderInt(name.data(String::Latin1), item));
|
||||
}
|
||||
else if (name == "rate") {
|
||||
const MP4::Item& item = it->second;
|
||||
else if(name == "rate") {
|
||||
StringList value = item.toStringList();
|
||||
if (value.isEmpty()) {
|
||||
data.append(renderInt(name.data(String::Latin1), item));
|
||||
@ -502,22 +502,22 @@ MP4::Tag::save()
|
||||
else if(name == "tvsn" || name == "tves" || name == "cnID" ||
|
||||
name == "sfID" || name == "atID" || name == "geID" ||
|
||||
name == "cmID") {
|
||||
data.append(renderUInt(name.data(String::Latin1), it->second));
|
||||
data.append(renderUInt(name.data(String::Latin1), item));
|
||||
}
|
||||
else if(name == "plID") {
|
||||
data.append(renderLongLong(name.data(String::Latin1), it->second));
|
||||
data.append(renderLongLong(name.data(String::Latin1), item));
|
||||
}
|
||||
else if(name == "stik" || name == "rtng" || name == "akID") {
|
||||
data.append(renderByte(name.data(String::Latin1), it->second));
|
||||
data.append(renderByte(name.data(String::Latin1), item));
|
||||
}
|
||||
else if(name == "covr") {
|
||||
data.append(renderCovr(name.data(String::Latin1), it->second));
|
||||
data.append(renderCovr(name.data(String::Latin1), item));
|
||||
}
|
||||
else if(name == "purl" || name == "egid") {
|
||||
data.append(renderText(name.data(String::Latin1), it->second, TypeImplicit));
|
||||
data.append(renderText(name.data(String::Latin1), item, TypeImplicit));
|
||||
}
|
||||
else if(name.size() == 4){
|
||||
data.append(renderText(name.data(String::Latin1), it->second));
|
||||
data.append(renderText(name.data(String::Latin1), item));
|
||||
}
|
||||
else {
|
||||
debug("MP4: Unknown item name \"" + name + "\"");
|
||||
@ -583,8 +583,7 @@ MP4::Tag::updateOffsets(offset_t delta, offset_t offset)
|
||||
MP4::Atom *moov = d->atoms->find("moov");
|
||||
if(moov) {
|
||||
const MP4::AtomList stco = moov->findall("stco", true);
|
||||
for(auto it = stco.begin(); it != stco.end(); ++it) {
|
||||
MP4::Atom *atom = *it;
|
||||
for(const auto &atom : stco) {
|
||||
if(atom->offset > offset) {
|
||||
atom->offset += delta;
|
||||
}
|
||||
@ -604,8 +603,7 @@ MP4::Tag::updateOffsets(offset_t delta, offset_t offset)
|
||||
}
|
||||
|
||||
const MP4::AtomList co64 = moov->findall("co64", true);
|
||||
for(auto it = co64.begin(); it != co64.end(); ++it) {
|
||||
MP4::Atom *atom = *it;
|
||||
for(const auto &atom : co64) {
|
||||
if(atom->offset > offset) {
|
||||
atom->offset += delta;
|
||||
}
|
||||
@ -628,8 +626,7 @@ MP4::Tag::updateOffsets(offset_t delta, offset_t offset)
|
||||
MP4::Atom *moof = d->atoms->find("moof");
|
||||
if(moof) {
|
||||
const MP4::AtomList tfhd = moof->findall("tfhd", true);
|
||||
for(auto it = tfhd.begin(); it != tfhd.end(); ++it) {
|
||||
MP4::Atom *atom = *it;
|
||||
for(const auto &atom : tfhd) {
|
||||
if(atom->offset > offset) {
|
||||
atom->offset += delta;
|
||||
}
|
||||
@ -688,8 +685,7 @@ MP4::Tag::saveExisting(ByteVector data, const AtomList &path)
|
||||
|
||||
// check if there is an atom before 'ilst', and possibly use it as padding
|
||||
if(index != meta->children.cbegin()) {
|
||||
auto prevIndex = index;
|
||||
prevIndex--;
|
||||
auto prevIndex = std::prev(index);
|
||||
MP4::Atom *prev = *prevIndex;
|
||||
if(prev->name == "free") {
|
||||
offset = prev->offset;
|
||||
@ -697,8 +693,7 @@ MP4::Tag::saveExisting(ByteVector data, const AtomList &path)
|
||||
}
|
||||
}
|
||||
// check if there is an atom after 'ilst', and possibly use it as padding
|
||||
auto nextIndex = index;
|
||||
nextIndex++;
|
||||
auto nextIndex = std::next(index);
|
||||
if(nextIndex != meta->children.cend()) {
|
||||
MP4::Atom *next = *nextIndex;
|
||||
if(next->name == "free") {
|
||||
@ -726,7 +721,7 @@ MP4::Tag::saveExisting(ByteVector data, const AtomList &path)
|
||||
}
|
||||
else {
|
||||
// Strip meta if data is empty, only the case when called from strip().
|
||||
MP4::Atom *udta = *(--it);
|
||||
MP4::Atom *udta = *std::prev(it);
|
||||
AtomList &udtaChildren = udta->children;
|
||||
auto metaIt = udtaChildren.find(meta);
|
||||
if(metaIt != udtaChildren.end()) {
|
||||
@ -980,31 +975,31 @@ namespace
|
||||
PropertyMap MP4::Tag::properties() const
|
||||
{
|
||||
PropertyMap props;
|
||||
for(auto it = d->items.cbegin(); it != d->items.cend(); ++it) {
|
||||
const String key = translateKey(it->first);
|
||||
for(const auto &[k, t] : std::as_const(d->items)) {
|
||||
const String key = translateKey(k);
|
||||
if(!key.isEmpty()) {
|
||||
if(key == "TRACKNUMBER" || key == "DISCNUMBER") {
|
||||
MP4::Item::IntPair ip = it->second.toIntPair();
|
||||
String value = String::number(ip.first);
|
||||
if(ip.second) {
|
||||
value += "/" + String::number(ip.second);
|
||||
auto [vn, tn] = t.toIntPair();
|
||||
String value = String::number(vn);
|
||||
if(tn) {
|
||||
value += "/" + String::number(tn);
|
||||
}
|
||||
props[key] = value;
|
||||
}
|
||||
else if(key == "BPM" || key == "MOVEMENTNUMBER" || key == "MOVEMENTCOUNT" ||
|
||||
key == "TVEPISODE" || key == "TVSEASON") {
|
||||
props[key] = String::number(it->second.toInt());
|
||||
props[key] = String::number(t.toInt());
|
||||
}
|
||||
else if(key == "COMPILATION" || key == "SHOWWORKMOVEMENT" ||
|
||||
key == "GAPLESSPLAYBACK" || key == "PODCAST") {
|
||||
props[key] = String::number(it->second.toBool());
|
||||
props[key] = String::number(t.toBool());
|
||||
}
|
||||
else {
|
||||
props[key] = it->second.toStringList();
|
||||
props[key] = t.toStringList();
|
||||
}
|
||||
}
|
||||
else {
|
||||
props.unsupportedData().append(it->first);
|
||||
props.unsupportedData().append(k);
|
||||
}
|
||||
}
|
||||
return props;
|
||||
@ -1012,8 +1007,8 @@ PropertyMap MP4::Tag::properties() const
|
||||
|
||||
void MP4::Tag::removeUnsupportedProperties(const StringList &props)
|
||||
{
|
||||
for(auto it = props.begin(); it != props.end(); ++it)
|
||||
d->items.erase(*it);
|
||||
for(const auto &prop : props)
|
||||
d->items.erase(prop);
|
||||
}
|
||||
|
||||
PropertyMap MP4::Tag::setProperties(const PropertyMap &props)
|
||||
@ -1026,18 +1021,18 @@ PropertyMap MP4::Tag::setProperties(const PropertyMap &props)
|
||||
}
|
||||
|
||||
const PropertyMap origProps = properties();
|
||||
for(auto it = origProps.begin(); it != origProps.end(); ++it) {
|
||||
if(!props.contains(it->first) || props[it->first].isEmpty()) {
|
||||
d->items.erase(reverseKeyMap[it->first]);
|
||||
for(const auto &[prop, _] : origProps) {
|
||||
if(!props.contains(prop) || props[prop].isEmpty()) {
|
||||
d->items.erase(reverseKeyMap[prop]);
|
||||
}
|
||||
}
|
||||
|
||||
PropertyMap ignoredProps;
|
||||
for(auto it = props.begin(); it != props.end(); ++it) {
|
||||
if(reverseKeyMap.contains(it->first)) {
|
||||
String name = reverseKeyMap[it->first];
|
||||
if((it->first == "TRACKNUMBER" || it->first == "DISCNUMBER") && !it->second.isEmpty()) {
|
||||
StringList parts = StringList::split(it->second.front(), "/");
|
||||
for(const auto &[prop, val] : props) {
|
||||
if(reverseKeyMap.contains(prop)) {
|
||||
String name = reverseKeyMap[prop];
|
||||
if((prop == "TRACKNUMBER" || prop == "DISCNUMBER") && !val.isEmpty()) {
|
||||
StringList parts = StringList::split(val.front(), "/");
|
||||
if(!parts.isEmpty()) {
|
||||
int first = parts[0].toInt();
|
||||
int second = 0;
|
||||
@ -1047,24 +1042,24 @@ PropertyMap MP4::Tag::setProperties(const PropertyMap &props)
|
||||
d->items[name] = MP4::Item(first, second);
|
||||
}
|
||||
}
|
||||
else if((it->first == "BPM" || it->first == "MOVEMENTNUMBER" ||
|
||||
it->first == "MOVEMENTCOUNT" || it->first == "TVEPISODE" ||
|
||||
it->first == "TVSEASON") && !it->second.isEmpty()) {
|
||||
int value = it->second.front().toInt();
|
||||
else if((prop == "BPM" || prop == "MOVEMENTNUMBER" ||
|
||||
prop == "MOVEMENTCOUNT" || prop == "TVEPISODE" ||
|
||||
prop == "TVSEASON") && !val.isEmpty()) {
|
||||
int value = val.front().toInt();
|
||||
d->items[name] = MP4::Item(value);
|
||||
}
|
||||
else if((it->first == "COMPILATION" || it->first == "SHOWWORKMOVEMENT" ||
|
||||
it->first == "GAPLESSPLAYBACK" || it->first == "PODCAST") &&
|
||||
!it->second.isEmpty()) {
|
||||
bool value = (it->second.front().toInt() != 0);
|
||||
else if((prop == "COMPILATION" || prop == "SHOWWORKMOVEMENT" ||
|
||||
prop == "GAPLESSPLAYBACK" || prop == "PODCAST") &&
|
||||
!val.isEmpty()) {
|
||||
bool value = (val.front().toInt() != 0);
|
||||
d->items[name] = MP4::Item(value);
|
||||
}
|
||||
else {
|
||||
d->items[name] = it->second;
|
||||
d->items[name] = val;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ignoredProps.insert(it->first, it->second);
|
||||
ignoredProps.insert(prop, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -26,9 +26,10 @@
|
||||
#include "chapterframe.h"
|
||||
|
||||
#include "tbytevectorlist.h"
|
||||
#include "tpropertymap.h"
|
||||
#include "tdebug.h"
|
||||
#include "tpropertymap.h"
|
||||
#include <cstdio>
|
||||
#include <utility>
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace ID3v2;
|
||||
@ -80,8 +81,8 @@ ChapterFrame::ChapterFrame(const ByteVector &elementID,
|
||||
d->startOffset = startOffset;
|
||||
d->endOffset = endOffset;
|
||||
|
||||
for(auto it = embeddedFrames.begin(); it != embeddedFrames.end(); ++it)
|
||||
addEmbeddedFrame(*it);
|
||||
for(const auto &frame : embeddedFrames)
|
||||
addEmbeddedFrame(frame);
|
||||
}
|
||||
|
||||
ChapterFrame::~ChapterFrame() = default;
|
||||
@ -177,9 +178,9 @@ void ChapterFrame::removeEmbeddedFrame(Frame *frame, bool del)
|
||||
|
||||
void ChapterFrame::removeEmbeddedFrames(const ByteVector &id)
|
||||
{
|
||||
const FrameList l = d->embeddedFrameListMap[id];
|
||||
for(auto it = l.begin(); it != l.end(); ++it)
|
||||
removeEmbeddedFrame(*it, true);
|
||||
const FrameList frames = d->embeddedFrameListMap[id];
|
||||
for(const auto &frame : frames)
|
||||
removeEmbeddedFrame(frame, true);
|
||||
}
|
||||
|
||||
String ChapterFrame::toString() const
|
||||
@ -196,8 +197,8 @@ String ChapterFrame::toString() const
|
||||
|
||||
if(!d->embeddedFrameList.isEmpty()) {
|
||||
StringList frameIDs;
|
||||
for(auto it = d->embeddedFrameList.cbegin(); it != d->embeddedFrameList.cend(); ++it)
|
||||
frameIDs.append((*it)->frameID());
|
||||
for(const auto &frame : std::as_const(d->embeddedFrameList))
|
||||
frameIDs.append(frame->frameID());
|
||||
s += ", sub-frames: [ " + frameIDs.toString(", ") + " ]";
|
||||
}
|
||||
|
||||
@ -215,13 +216,8 @@ PropertyMap ChapterFrame::asProperties() const
|
||||
|
||||
ChapterFrame *ChapterFrame::findByElementID(const ID3v2::Tag *tag, const ByteVector &eID) // static
|
||||
{
|
||||
ID3v2::FrameList comments = tag->frameList("CHAP");
|
||||
|
||||
for(auto it = comments.cbegin();
|
||||
it != comments.cend();
|
||||
++it)
|
||||
{
|
||||
auto frame = dynamic_cast<ChapterFrame *>(*it);
|
||||
for(const auto &comment : std::as_const(tag->frameList("CHAP"))) {
|
||||
auto frame = dynamic_cast<ChapterFrame *>(comment);
|
||||
if(frame && frame->elementID() == eID)
|
||||
return frame;
|
||||
}
|
||||
@ -283,10 +279,9 @@ ByteVector ChapterFrame::renderFields() const
|
||||
data.append(ByteVector::fromUInt(d->endTime, true));
|
||||
data.append(ByteVector::fromUInt(d->startOffset, true));
|
||||
data.append(ByteVector::fromUInt(d->endOffset, true));
|
||||
const FrameList l = d->embeddedFrameList;
|
||||
for(auto it = l.begin(); it != l.end(); ++it) {
|
||||
(*it)->header()->setVersion(header()->version());
|
||||
data.append((*it)->render());
|
||||
for(const auto &frame : std::as_const(d->embeddedFrameList)) {
|
||||
frame->header()->setVersion(header()->version());
|
||||
data.append(frame->render());
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
@ -25,6 +25,8 @@
|
||||
|
||||
#include "commentsframe.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "tbytevectorlist.h"
|
||||
#include "id3v2tag.h"
|
||||
#include "tdebug.h"
|
||||
@ -122,11 +124,8 @@ PropertyMap CommentsFrame::asProperties() const
|
||||
|
||||
CommentsFrame *CommentsFrame::findByDescription(const ID3v2::Tag *tag, const String &d) // static
|
||||
{
|
||||
const ID3v2::FrameList comments = tag->frameList("COMM");
|
||||
|
||||
for(auto it = comments.begin(); it != comments.end(); ++it)
|
||||
{
|
||||
auto frame = dynamic_cast<CommentsFrame *>(*it);
|
||||
for(const auto &comment : std::as_const(tag->frameList("COMM"))) {
|
||||
auto frame = dynamic_cast<CommentsFrame *>(comment);
|
||||
if(frame && frame->description() == d)
|
||||
return frame;
|
||||
}
|
||||
|
||||
@ -29,6 +29,8 @@
|
||||
#include "tdebug.h"
|
||||
#include "tpropertymap.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace ID3v2;
|
||||
|
||||
@ -116,8 +118,7 @@ ByteVector EventTimingCodesFrame::renderFields() const
|
||||
ByteVector v;
|
||||
|
||||
v.append(static_cast<char>(d->timestampFormat));
|
||||
for(auto it = d->synchedEvents.cbegin(); it != d->synchedEvents.cend(); ++it) {
|
||||
const SynchedEvent &entry = *it;
|
||||
for(const auto &entry : std::as_const(d->synchedEvents)) {
|
||||
v.append(static_cast<char>(entry.type));
|
||||
v.append(ByteVector::fromUInt(entry.time));
|
||||
}
|
||||
|
||||
@ -28,6 +28,8 @@
|
||||
#include "tdebug.h"
|
||||
#include "tmap.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace ID3v2;
|
||||
|
||||
@ -73,8 +75,8 @@ List<RelativeVolumeFrame::ChannelType> RelativeVolumeFrame::channels() const
|
||||
{
|
||||
List<ChannelType> l;
|
||||
|
||||
for(auto it = d->channels.cbegin(); it != d->channels.cend(); ++it)
|
||||
l.append((*it).first);
|
||||
for(const auto &[type, channel] : std::as_const(d->channels))
|
||||
l.append(type);
|
||||
|
||||
return l;
|
||||
}
|
||||
@ -156,10 +158,7 @@ ByteVector RelativeVolumeFrame::renderFields() const
|
||||
data.append(d->identification.data(String::Latin1));
|
||||
data.append(textDelimiter(String::Latin1));
|
||||
|
||||
for(auto it = d->channels.cbegin(); it != d->channels.cend(); ++it) {
|
||||
ChannelType type = (*it).first;
|
||||
const ChannelData &channel = (*it).second;
|
||||
|
||||
for(const auto &[type, channel] : std::as_const(d->channels)) {
|
||||
data.append(static_cast<char>(type));
|
||||
data.append(ByteVector::fromShort(channel.volumeAdjustment));
|
||||
data.append(static_cast<char>(channel.peakVolume.bitsRepresentingPeak));
|
||||
|
||||
@ -29,6 +29,8 @@
|
||||
#include "tdebug.h"
|
||||
#include "tpropertymap.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace ID3v2;
|
||||
|
||||
@ -199,10 +201,8 @@ ByteVector SynchronizedLyricsFrame::renderFields() const
|
||||
String::Type encoding = d->textEncoding;
|
||||
|
||||
encoding = checkTextEncoding(d->description, encoding);
|
||||
for(auto it = d->synchedText.cbegin();
|
||||
it != d->synchedText.cend();
|
||||
++it) {
|
||||
encoding = checkTextEncoding(it->text, encoding);
|
||||
for(const auto &frame : std::as_const(d->synchedText)) {
|
||||
encoding = checkTextEncoding(frame.text, encoding);
|
||||
}
|
||||
|
||||
v.append(static_cast<char>(encoding));
|
||||
@ -211,8 +211,7 @@ ByteVector SynchronizedLyricsFrame::renderFields() const
|
||||
v.append(static_cast<char>(d->type));
|
||||
v.append(d->description.data(encoding));
|
||||
v.append(textDelimiter(encoding));
|
||||
for(auto it = d->synchedText.cbegin(); it != d->synchedText.cend(); ++it) {
|
||||
const SynchedText &entry = *it;
|
||||
for(const auto &entry : std::as_const(d->synchedText)) {
|
||||
v.append(entry.text.data(encoding));
|
||||
v.append(textDelimiter(encoding));
|
||||
v.append(ByteVector::fromUInt(entry.time));
|
||||
|
||||
@ -29,6 +29,8 @@
|
||||
#include "tpropertymap.h"
|
||||
#include "tdebug.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace ID3v2;
|
||||
|
||||
@ -66,9 +68,8 @@ namespace {
|
||||
|
||||
ByteVectorList &strip(ByteVectorList &l)
|
||||
{
|
||||
for(auto it = l.begin(); it != l.end(); ++it)
|
||||
{
|
||||
strip(*it);
|
||||
for(auto &v : l) {
|
||||
strip(v);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
@ -96,8 +97,8 @@ TableOfContentsFrame::TableOfContentsFrame(const ByteVector &elementID,
|
||||
strip(d->elementID);
|
||||
d->childElements = children;
|
||||
|
||||
for(auto it = embeddedFrames.begin(); it != embeddedFrames.end(); ++it)
|
||||
addEmbeddedFrame(*it);
|
||||
for(const auto &frame : embeddedFrames)
|
||||
addEmbeddedFrame(frame);
|
||||
}
|
||||
|
||||
TableOfContentsFrame::~TableOfContentsFrame() = default;
|
||||
@ -207,9 +208,9 @@ void TableOfContentsFrame::removeEmbeddedFrame(Frame *frame, bool del)
|
||||
|
||||
void TableOfContentsFrame::removeEmbeddedFrames(const ByteVector &id)
|
||||
{
|
||||
const FrameList l = d->embeddedFrameListMap[id];
|
||||
for(auto it = l.begin(); it != l.end(); ++it)
|
||||
removeEmbeddedFrame(*it, true);
|
||||
const FrameList frames = d->embeddedFrameListMap[id];
|
||||
for(const auto &frame : frames)
|
||||
removeEmbeddedFrame(frame, true);
|
||||
}
|
||||
|
||||
String TableOfContentsFrame::toString() const
|
||||
@ -224,8 +225,8 @@ String TableOfContentsFrame::toString() const
|
||||
|
||||
if(!d->embeddedFrameList.isEmpty()) {
|
||||
StringList frameIDs;
|
||||
for(auto it = d->embeddedFrameList.cbegin(); it != d->embeddedFrameList.cend(); ++it)
|
||||
frameIDs.append((*it)->frameID());
|
||||
for(const auto &frame : std::as_const(d->embeddedFrameList))
|
||||
frameIDs.append(frame->frameID());
|
||||
s += ", sub-frames: [ " + frameIDs.toString(", ") + " ]";
|
||||
}
|
||||
|
||||
@ -244,13 +245,8 @@ PropertyMap TableOfContentsFrame::asProperties() const
|
||||
TableOfContentsFrame *TableOfContentsFrame::findByElementID(const ID3v2::Tag *tag,
|
||||
const ByteVector &eID) // static
|
||||
{
|
||||
const ID3v2::FrameList tablesOfContents = tag->frameList("CTOC");
|
||||
|
||||
for(auto it = tablesOfContents.begin();
|
||||
it != tablesOfContents.end();
|
||||
++it)
|
||||
{
|
||||
auto frame = dynamic_cast<TableOfContentsFrame *>(*it);
|
||||
for(const auto &table : std::as_const(tag->frameList("CTOC"))) {
|
||||
auto frame = dynamic_cast<TableOfContentsFrame *>(table);
|
||||
if(frame && frame->elementID() == eID)
|
||||
return frame;
|
||||
}
|
||||
@ -260,11 +256,8 @@ TableOfContentsFrame *TableOfContentsFrame::findByElementID(const ID3v2::Tag *ta
|
||||
|
||||
TableOfContentsFrame *TableOfContentsFrame::findTopLevel(const ID3v2::Tag *tag) // static
|
||||
{
|
||||
const ID3v2::FrameList tablesOfContents = tag->frameList("CTOC");
|
||||
|
||||
for(auto it = tablesOfContents.begin(); it != tablesOfContents.end(); ++it)
|
||||
{
|
||||
auto frame = dynamic_cast<TableOfContentsFrame *>(*it);
|
||||
for(const auto &table : std::as_const(tag->frameList("CTOC"))) {
|
||||
auto frame = dynamic_cast<TableOfContentsFrame *>(table);
|
||||
if(frame && frame->isTopLevel())
|
||||
return frame;
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#include "id3v1genres.h"
|
||||
|
||||
#include <array>
|
||||
#include <utility>
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace ID3v2;
|
||||
@ -67,12 +68,12 @@ TextIdentificationFrame *TextIdentificationFrame::createTIPLFrame(const Property
|
||||
{
|
||||
auto frame = new TextIdentificationFrame("TIPL");
|
||||
StringList l;
|
||||
for(auto it = properties.begin(); it != properties.end(); ++it){
|
||||
const String role = involvedPeopleMap()[it->first];
|
||||
for(const auto &[person, list] : properties) {
|
||||
const String role = involvedPeopleMap()[person];
|
||||
if(role.isEmpty()) // should not happen
|
||||
continue;
|
||||
l.append(role);
|
||||
l.append(it->second.toString(",")); // comma-separated list of names
|
||||
l.append(list.toString(",")); // comma-separated list of names
|
||||
}
|
||||
frame->setText(l);
|
||||
return frame;
|
||||
@ -82,11 +83,11 @@ TextIdentificationFrame *TextIdentificationFrame::createTMCLFrame(const Property
|
||||
{
|
||||
auto frame = new TextIdentificationFrame("TMCL");
|
||||
StringList l;
|
||||
for(auto it = properties.begin(); it != properties.end(); ++it){
|
||||
if(!it->first.startsWith(instrumentPrefix)) // should not happen
|
||||
for(const auto &[instrument, list] : properties) {
|
||||
if(!instrument.startsWith(instrumentPrefix)) // should not happen
|
||||
continue;
|
||||
l.append(it->first.substr(instrumentPrefix.size()));
|
||||
l.append(it->second.toString(","));
|
||||
l.append(instrument.substr(instrumentPrefix.size()));
|
||||
l.append(list.toString(","));
|
||||
}
|
||||
frame->setText(l);
|
||||
return frame;
|
||||
@ -162,19 +163,19 @@ PropertyMap TextIdentificationFrame::asProperties() const
|
||||
if(tagName == "GENRE") {
|
||||
// Special case: Support ID3v1-style genre numbers. They are not officially supported in
|
||||
// ID3v2, however it seems that still a lot of programs use them.
|
||||
for(auto it = values.begin(); it != values.end(); ++it) {
|
||||
for(auto &value : values) {
|
||||
bool ok = false;
|
||||
int test = it->toInt(&ok); // test if the genre value is an integer
|
||||
int test = value.toInt(&ok); // test if the genre value is an integer
|
||||
if(ok)
|
||||
*it = ID3v1::genre(test);
|
||||
value = ID3v1::genre(test);
|
||||
}
|
||||
} else if(tagName == "DATE") {
|
||||
for(auto it = values.begin(); it != values.end(); ++it) {
|
||||
for(auto &value : values) {
|
||||
// ID3v2 specifies ISO8601 timestamps which contain a 'T' as separator between date and time.
|
||||
// Since this is unusual in other formats, the T is removed.
|
||||
int tpos = it->find("T");
|
||||
int tpos = value.find("T");
|
||||
if(tpos != -1)
|
||||
(*it)[tpos] = ' ';
|
||||
value[tpos] = ' ';
|
||||
}
|
||||
}
|
||||
PropertyMap ret;
|
||||
@ -414,18 +415,16 @@ PropertyMap UserTextIdentificationFrame::asProperties() const
|
||||
PropertyMap map;
|
||||
String tagName = txxxToKey(description());
|
||||
const StringList v = fieldList();
|
||||
for(auto it = v.begin(); it != v.end(); ++it)
|
||||
if(it != v.begin())
|
||||
map.insert(tagName, *it);
|
||||
for(auto it = std::next(v.begin()); it != v.end(); ++it)
|
||||
map.insert(tagName, *it);
|
||||
return map;
|
||||
}
|
||||
|
||||
UserTextIdentificationFrame *UserTextIdentificationFrame::find(
|
||||
ID3v2::Tag *tag, const String &description) // static
|
||||
{
|
||||
const FrameList l = tag->frameList("TXXX");
|
||||
for(auto it = l.begin(); it != l.end(); ++it) {
|
||||
auto f = dynamic_cast<UserTextIdentificationFrame *>(*it);
|
||||
for(const auto &frame : std::as_const(tag->frameList("TXXX"))) {
|
||||
auto f = dynamic_cast<UserTextIdentificationFrame *>(frame);
|
||||
if(f && f->description() == description)
|
||||
return f;
|
||||
}
|
||||
|
||||
@ -25,6 +25,8 @@
|
||||
|
||||
#include "uniquefileidentifierframe.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "tbytevectorlist.h"
|
||||
#include "tpropertymap.h"
|
||||
#include "tdebug.h"
|
||||
@ -101,11 +103,8 @@ PropertyMap UniqueFileIdentifierFrame::asProperties() const
|
||||
|
||||
UniqueFileIdentifierFrame *UniqueFileIdentifierFrame::findByOwner(const ID3v2::Tag *tag, const String &o) // static
|
||||
{
|
||||
const ID3v2::FrameList comments = tag->frameList("UFID");
|
||||
|
||||
for(auto it = comments.begin(); it != comments.end(); ++it)
|
||||
{
|
||||
auto frame = dynamic_cast<UniqueFileIdentifierFrame *>(*it);
|
||||
for(const auto &comment : std::as_const(tag->frameList("UFID"))) {
|
||||
auto frame = dynamic_cast<UniqueFileIdentifierFrame *>(comment);
|
||||
if(frame && frame->owner() == o)
|
||||
return frame;
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "unsynchronizedlyricsframe.h"
|
||||
#include <utility>
|
||||
#include "tbytevectorlist.h"
|
||||
#include "id3v2tag.h"
|
||||
#include "tdebug.h"
|
||||
@ -123,10 +124,8 @@ PropertyMap UnsynchronizedLyricsFrame::asProperties() const
|
||||
|
||||
UnsynchronizedLyricsFrame *UnsynchronizedLyricsFrame::findByDescription(const ID3v2::Tag *tag, const String &d) // static
|
||||
{
|
||||
const ID3v2::FrameList lyrics = tag->frameList("USLT");
|
||||
|
||||
for(auto it = lyrics.begin(); it != lyrics.end(); ++it){
|
||||
auto frame = dynamic_cast<UnsynchronizedLyricsFrame *>(*it);
|
||||
for(const auto &lyrics : std::as_const(tag->frameList("USLT"))) {
|
||||
auto frame = dynamic_cast<UnsynchronizedLyricsFrame *>(lyrics);
|
||||
if(frame && frame->description() == d)
|
||||
return frame;
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "urllinkframe.h"
|
||||
#include <utility>
|
||||
#include "id3v2tag.h"
|
||||
#include "tdebug.h"
|
||||
#include "tstringlist.h"
|
||||
@ -172,9 +173,8 @@ PropertyMap UserUrlLinkFrame::asProperties() const
|
||||
|
||||
UserUrlLinkFrame *UserUrlLinkFrame::find(ID3v2::Tag *tag, const String &description) // static
|
||||
{
|
||||
const FrameList l = tag->frameList("WXXX");
|
||||
for(auto it = l.begin(); it != l.end(); ++it) {
|
||||
auto f = dynamic_cast<UserUrlLinkFrame *>(*it);
|
||||
for(const auto &frame : std::as_const(tag->frameList("WXXX"))) {
|
||||
auto f = dynamic_cast<UserUrlLinkFrame *>(frame);
|
||||
if(f && f->description() == description)
|
||||
return f;
|
||||
}
|
||||
|
||||
@ -283,8 +283,8 @@ String::Type Frame::checkTextEncoding(const StringList &fields, String::Type enc
|
||||
if(encoding != String::Latin1)
|
||||
return encoding;
|
||||
|
||||
for(auto it = fields.begin(); it != fields.end(); ++it) {
|
||||
if(!(*it).isLatin1()) {
|
||||
for(const auto &field : fields) {
|
||||
if(!field.isLatin1()) {
|
||||
if(header()->version() == 4) {
|
||||
debug("Frame::checkEncoding() -- Rendering using UTF8.");
|
||||
return String::UTF8;
|
||||
@ -465,13 +465,13 @@ void Frame::splitProperties(const PropertyMap &original, PropertyMap &singleFram
|
||||
singleFrameProperties.clear();
|
||||
tiplProperties.clear();
|
||||
tmclProperties.clear();
|
||||
for(auto it = original.begin(); it != original.end(); ++it) {
|
||||
if(TextIdentificationFrame::involvedPeopleMap().contains(it->first))
|
||||
tiplProperties.insert(it->first, it->second);
|
||||
else if(it->first.startsWith(TextIdentificationFrame::instrumentPrefix))
|
||||
tmclProperties.insert(it->first, it->second);
|
||||
for(const auto &[person, tag] : original) {
|
||||
if(TextIdentificationFrame::involvedPeopleMap().contains(person))
|
||||
tiplProperties.insert(person, tag);
|
||||
else if(person.startsWith(TextIdentificationFrame::instrumentPrefix))
|
||||
tmclProperties.insert(person, tag);
|
||||
else
|
||||
singleFrameProperties.insert(it->first, it->second);
|
||||
singleFrameProperties.insert(person, tag);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -50,6 +50,7 @@
|
||||
#include "frames/podcastframe.h"
|
||||
|
||||
#include <array>
|
||||
#include <utility>
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace ID3v2;
|
||||
@ -61,8 +62,7 @@ namespace
|
||||
StringList fields = frame->fieldList();
|
||||
StringList newfields;
|
||||
|
||||
for(auto it = fields.cbegin(); it != fields.cend(); ++it) {
|
||||
String s = *it;
|
||||
for(auto s : std::as_const(fields)) {
|
||||
int offset = 0;
|
||||
int end = 0;
|
||||
|
||||
|
||||
@ -199,8 +199,8 @@ void Header::parse(const ByteVector &data)
|
||||
return;
|
||||
}
|
||||
|
||||
for(auto it = sizeData.begin(); it != sizeData.end(); it++) {
|
||||
if(static_cast<unsigned char>(*it) >= 128) {
|
||||
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;
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include "id3v2tag.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#include "tfile.h"
|
||||
#include "tbytevector.h"
|
||||
@ -164,12 +165,10 @@ String ID3v2::Tag::comment() const
|
||||
if(comments.isEmpty())
|
||||
return String();
|
||||
|
||||
for(auto it = comments.begin(); it != comments.end(); ++it)
|
||||
{
|
||||
auto frame = dynamic_cast<CommentsFrame *>(*it);
|
||||
|
||||
for(const auto &comment : comments) {
|
||||
auto frame = dynamic_cast<CommentsFrame *>(comment);
|
||||
if(frame && frame->description().isEmpty())
|
||||
return (*it)->toString();
|
||||
return comment->toString();
|
||||
}
|
||||
|
||||
return comments.front()->toString();
|
||||
@ -199,23 +198,21 @@ String ID3v2::Tag::genre() const
|
||||
// appended to the genre string. Multiple fields will be appended as the
|
||||
// string is built.
|
||||
|
||||
StringList fields = f->fieldList();
|
||||
|
||||
StringList genres;
|
||||
|
||||
for(auto it = fields.begin(); it != fields.end(); ++it) {
|
||||
for(auto &field : f->fieldList()) {
|
||||
|
||||
if((*it).isEmpty())
|
||||
if(field.isEmpty())
|
||||
continue;
|
||||
|
||||
bool ok;
|
||||
int number = (*it).toInt(&ok);
|
||||
int number = field.toInt(&ok);
|
||||
if(ok && number >= 0 && number <= 255) {
|
||||
*it = ID3v1::genre(number);
|
||||
field = ID3v1::genre(number);
|
||||
}
|
||||
|
||||
if(std::find(genres.begin(), genres.end(), *it) == genres.end())
|
||||
genres.append(*it);
|
||||
if(std::find(genres.begin(), genres.end(), field) == genres.end())
|
||||
genres.append(field);
|
||||
}
|
||||
|
||||
return genres.toString();
|
||||
@ -260,10 +257,10 @@ void ID3v2::Tag::setComment(const String &s)
|
||||
const FrameList &comments = d->frameListMap["COMM"];
|
||||
|
||||
if(!comments.isEmpty()) {
|
||||
for(auto it = comments.begin(); it != comments.end(); ++it) {
|
||||
auto frame = dynamic_cast<CommentsFrame *>(*it);
|
||||
for(const auto &comment : comments) {
|
||||
auto frame = dynamic_cast<CommentsFrame *>(comment);
|
||||
if(frame && frame->description().isEmpty()) {
|
||||
(*it)->setText(s);
|
||||
comment->setText(s);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -374,17 +371,16 @@ void ID3v2::Tag::removeFrame(Frame *frame, bool del)
|
||||
|
||||
void ID3v2::Tag::removeFrames(const ByteVector &id)
|
||||
{
|
||||
const FrameList l = d->frameListMap[id];
|
||||
for(auto it = l.begin(); it != l.end(); ++it)
|
||||
removeFrame(*it, true);
|
||||
const FrameList frames = d->frameListMap[id];
|
||||
for(const auto &frame : frames)
|
||||
removeFrame(frame, true);
|
||||
}
|
||||
|
||||
PropertyMap ID3v2::Tag::properties() const
|
||||
{
|
||||
PropertyMap properties;
|
||||
const auto &frames = frameList();
|
||||
for(auto it = frames.begin(); it != frames.end(); ++it) {
|
||||
PropertyMap props = (*it)->asProperties();
|
||||
for(const auto &frame : std::as_const(frameList())) {
|
||||
PropertyMap props = frame->asProperties();
|
||||
properties.merge(props);
|
||||
}
|
||||
return properties;
|
||||
@ -392,27 +388,27 @@ PropertyMap ID3v2::Tag::properties() const
|
||||
|
||||
void ID3v2::Tag::removeUnsupportedProperties(const StringList &properties)
|
||||
{
|
||||
for(auto it = properties.begin(); it != properties.end(); ++it){
|
||||
if(it->startsWith("UNKNOWN/")) {
|
||||
String frameID = it->substr(String("UNKNOWN/").size());
|
||||
for(const auto &property : properties) {
|
||||
if(property.startsWith("UNKNOWN/")) {
|
||||
String frameID = property.substr(String("UNKNOWN/").size());
|
||||
if(frameID.size() != 4)
|
||||
continue; // invalid specification
|
||||
ByteVector id = frameID.data(String::Latin1);
|
||||
// delete all unknown frames of given type
|
||||
const FrameList l = frameList(id);
|
||||
for(auto fit = l.begin(); fit != l.end(); fit++)
|
||||
if (dynamic_cast<const UnknownFrame *>(*fit) != nullptr)
|
||||
removeFrame(*fit);
|
||||
const FrameList frames = frameList(id);
|
||||
for(const auto &frame : frames)
|
||||
if(dynamic_cast<const UnknownFrame *>(frame) != nullptr)
|
||||
removeFrame(frame);
|
||||
}
|
||||
else if(it->size() == 4){
|
||||
ByteVector id = it->data(String::Latin1);
|
||||
else if(property.size() == 4) {
|
||||
ByteVector id = property.data(String::Latin1);
|
||||
removeFrames(id);
|
||||
}
|
||||
else {
|
||||
ByteVector id = it->substr(0,4).data(String::Latin1);
|
||||
if(it->size() <= 5)
|
||||
ByteVector id = property.substr(0, 4).data(String::Latin1);
|
||||
if(property.size() <= 5)
|
||||
continue; // invalid specification
|
||||
String description = it->substr(5);
|
||||
String description = property.substr(5);
|
||||
Frame *frame = nullptr;
|
||||
if(id == "TXXX")
|
||||
frame = UserTextIdentificationFrame::find(this, description);
|
||||
@ -439,28 +435,29 @@ PropertyMap ID3v2::Tag::setProperties(const PropertyMap &origProps)
|
||||
PropertyMap tiplProperties;
|
||||
PropertyMap tmclProperties;
|
||||
Frame::splitProperties(origProps, properties, tiplProperties, tmclProperties);
|
||||
const auto &frames = frameListMap();
|
||||
for(auto it = frames.begin(); it != frames.end(); ++it){
|
||||
for(auto lit = it->second.begin(); lit != it->second.end(); ++lit){
|
||||
PropertyMap frameProperties = (*lit)->asProperties();
|
||||
if(it->first == "TIPL") {
|
||||
for(const auto &[tag, frames] : std::as_const(frameListMap())) {
|
||||
for(const auto &frame : frames) {
|
||||
PropertyMap frameProperties = frame->asProperties();
|
||||
if(tag == "TIPL") {
|
||||
if (tiplProperties != frameProperties)
|
||||
framesToDelete.append(*lit);
|
||||
framesToDelete.append(frame);
|
||||
else
|
||||
tiplProperties.erase(frameProperties);
|
||||
} else if(it->first == "TMCL") {
|
||||
}
|
||||
else if(tag == "TMCL") {
|
||||
if (tmclProperties != frameProperties)
|
||||
framesToDelete.append(*lit);
|
||||
framesToDelete.append(frame);
|
||||
else
|
||||
tmclProperties.erase(frameProperties);
|
||||
} else if(!properties.contains(frameProperties))
|
||||
framesToDelete.append(*lit);
|
||||
}
|
||||
else if(!properties.contains(frameProperties))
|
||||
framesToDelete.append(frame);
|
||||
else
|
||||
properties.erase(frameProperties);
|
||||
}
|
||||
}
|
||||
for(auto it = framesToDelete.cbegin(); it != framesToDelete.cend(); ++it)
|
||||
removeFrame(*it);
|
||||
for(const auto &frame : std::as_const(framesToDelete))
|
||||
removeFrame(frame);
|
||||
|
||||
// now create remaining frames:
|
||||
// start with the involved people list (TIPL)
|
||||
@ -470,8 +467,8 @@ PropertyMap ID3v2::Tag::setProperties(const PropertyMap &origProps)
|
||||
if(!tmclProperties.isEmpty())
|
||||
addFrame(TextIdentificationFrame::createTMCLFrame(tmclProperties));
|
||||
// now create the "one key per frame" frames
|
||||
for(auto it = properties.cbegin(); it != properties.cend(); ++it)
|
||||
addFrame(Frame::createTextualFrame(it->first, it->second));
|
||||
for(const auto &[tag, frames] : std::as_const(properties))
|
||||
addFrame(Frame::createTextualFrame(tag, frames));
|
||||
return PropertyMap(); // ID3 implements the complete PropertyMap interface, so an empty map is returned
|
||||
}
|
||||
|
||||
@ -500,12 +497,10 @@ void ID3v2::Tag::downgradeFrames(FrameList *frames, FrameList *newFrames) const
|
||||
ID3v2::TextIdentificationFrame *frameTMCL = nullptr;
|
||||
ID3v2::TextIdentificationFrame *frameTCON = nullptr;
|
||||
|
||||
for(auto it = d->frameList.cbegin(); it != d->frameList.cend(); it++) {
|
||||
ID3v2::Frame *frame = *it;
|
||||
for(const auto &frame : std::as_const(d->frameList)) {
|
||||
ByteVector frameID = frame->header()->frameID();
|
||||
|
||||
if(contains(unsupportedFrames, frameID))
|
||||
{
|
||||
if(contains(unsupportedFrames, frameID)) {
|
||||
debug("A frame that is not supported in ID3v2.3 \'" + String(frameID) +
|
||||
"\' has been discarded");
|
||||
continue;
|
||||
@ -592,15 +587,15 @@ void ID3v2::Tag::downgradeFrames(FrameList *frames, FrameList *newFrames) const
|
||||
// If there are multiple genres, add them as multiple references to ID3v1
|
||||
// genres if such a reference exists. The first genre for which no ID3v1
|
||||
// genre number exists can be finally added as a refinement.
|
||||
for(auto it = genres.begin(); it != genres.end(); ++it) {
|
||||
for(const auto &genre : genres) {
|
||||
bool ok = false;
|
||||
int number = it->toInt(&ok);
|
||||
if((ok && number >= 0 && number <= 255) || *it == "RX" || *it == "CR")
|
||||
combined += '(' + *it + ')';
|
||||
else if(hasMultipleGenres && (number = ID3v1::genreIndex(*it)) != 255)
|
||||
int number = genre.toInt(&ok);
|
||||
if((ok && number >= 0 && number <= 255) || genre == "RX" || genre == "CR")
|
||||
combined += '(' + genre + ')';
|
||||
else if(hasMultipleGenres && (number = ID3v1::genreIndex(genre)) != 255)
|
||||
combined += '(' + String::number(number) + ')';
|
||||
else if(genreText.isEmpty())
|
||||
genreText = *it;
|
||||
genreText = genre;
|
||||
}
|
||||
if(!genreText.isEmpty())
|
||||
combined += genreText;
|
||||
@ -640,18 +635,18 @@ ByteVector ID3v2::Tag::render(Version version) const
|
||||
|
||||
// Loop through the frames rendering them and adding them to the tagData.
|
||||
|
||||
for(auto it = frameList.cbegin(); it != frameList.cend(); it++) {
|
||||
(*it)->header()->setVersion(version == v3 ? 3 : 4);
|
||||
if((*it)->header()->frameID().size() != 4) {
|
||||
for(const auto &frame : std::as_const(frameList)) {
|
||||
frame->header()->setVersion(version == v3 ? 3 : 4);
|
||||
if(frame->header()->frameID().size() != 4) {
|
||||
debug("An ID3v2 frame of unsupported or unknown type \'"
|
||||
+ String((*it)->header()->frameID()) + "\' has been discarded");
|
||||
+ String(frame->header()->frameID()) + "\' has been discarded");
|
||||
continue;
|
||||
}
|
||||
if(!(*it)->header()->tagAlterPreservation()) {
|
||||
const ByteVector frameData = (*it)->render();
|
||||
if(frameData.size() == (*it)->headerSize()) {
|
||||
if(!frame->header()->tagAlterPreservation()) {
|
||||
const ByteVector frameData = frame->render();
|
||||
if(frameData.size() == frame->headerSize()) {
|
||||
debug("An empty ID3v2 frame \'"
|
||||
+ String((*it)->header()->frameID()) + "\' has been discarded");
|
||||
+ String(frame->header()->frameID()) + "\' has been discarded");
|
||||
continue;
|
||||
}
|
||||
tagData.append(frameData);
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <utility>
|
||||
|
||||
#include "tstring.h"
|
||||
#include "tdebug.h"
|
||||
@ -92,8 +93,8 @@ unsigned int pageChecksum(const ByteVector &data)
|
||||
};
|
||||
|
||||
unsigned int sum = 0;
|
||||
for(auto it = data.begin(); it != data.end(); ++it)
|
||||
sum = (sum << 8) ^ crcTable[((sum >> 24) & 0xff) ^ static_cast<unsigned char>(*it)];
|
||||
for(const auto &byte : data)
|
||||
sum = (sum << 8) ^ crcTable[((sum >> 24) & 0xff) ^ static_cast<unsigned char>(byte)];
|
||||
return sum;
|
||||
}
|
||||
|
||||
@ -212,9 +213,8 @@ ByteVectorList Ogg::Page::packets() const
|
||||
d->file->seek(d->fileOffset + d->header.size());
|
||||
|
||||
const List<int> packetSizes = d->header.packetSizes();
|
||||
|
||||
for(auto it = packetSizes.begin(); it != packetSizes.end(); ++it)
|
||||
l.append(d->file->readBlock(*it));
|
||||
for(const auto &size : packetSizes)
|
||||
l.append(d->file->readBlock(size));
|
||||
}
|
||||
else
|
||||
debug("Ogg::Page::packets() -- attempting to read packets from an invalid page.");
|
||||
@ -242,8 +242,8 @@ ByteVector Ogg::Page::render() const
|
||||
debug("Ogg::Page::render() -- this page is empty!");
|
||||
}
|
||||
else {
|
||||
for(auto it = d->packets.cbegin(); it != d->packets.cend(); ++it)
|
||||
data.append(*it);
|
||||
for(const auto &packet : std::as_const(d->packets))
|
||||
data.append(packet);
|
||||
}
|
||||
|
||||
// Compute and set the checksum for the Ogg page. The checksum is taken over
|
||||
@ -274,8 +274,8 @@ List<Ogg::Page *> Ogg::Page::paginate(const ByteVectorList &packets,
|
||||
if(strategy != Repaginate) {
|
||||
|
||||
size_t tableSize = 0;
|
||||
for(auto it = packets.begin(); it != packets.end(); ++it)
|
||||
tableSize += it->size() / 255 + 1;
|
||||
for(const auto &packet : packets)
|
||||
tableSize += packet.size() / 255 + 1;
|
||||
|
||||
if(tableSize > 255)
|
||||
strategy = Repaginate;
|
||||
@ -354,9 +354,9 @@ Ogg::Page::Page(const ByteVectorList &packets,
|
||||
ByteVector data;
|
||||
List<int> packetSizes;
|
||||
|
||||
for(auto it = packets.begin(); it != packets.end(); ++it) {
|
||||
packetSizes.append((*it).size());
|
||||
data.append(*it);
|
||||
for(const auto &packet : packets) {
|
||||
packetSizes.append(packet.size());
|
||||
data.append(packet);
|
||||
}
|
||||
d->packets = packets;
|
||||
d->header.setPacketSizes(packetSizes);
|
||||
|
||||
@ -290,7 +290,7 @@ ByteVector Ogg::PageHeader::lacingValues() const
|
||||
|
||||
data.resize(data.size() + (*it / 255), '\xff');
|
||||
|
||||
if(it != --d->packetSizes.cend() || d->lastPacketCompleted)
|
||||
if(it != std::prev(d->packetSizes.cend()) || d->lastPacketCompleted)
|
||||
data.append(static_cast<unsigned char>(*it % 255));
|
||||
}
|
||||
|
||||
|
||||
@ -31,6 +31,8 @@
|
||||
#include "flacpicture.h"
|
||||
#include "tpropertymap.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
namespace
|
||||
@ -196,8 +198,8 @@ unsigned int Ogg::XiphComment::fieldCount() const
|
||||
{
|
||||
unsigned int count = 0;
|
||||
|
||||
for(auto it = d->fieldListMap.cbegin(); it != d->fieldListMap.cend(); ++it)
|
||||
count += (*it).second.size();
|
||||
for(const auto &[_, list] : std::as_const(d->fieldListMap))
|
||||
count += list.size();
|
||||
|
||||
count += d->pictureList.size();
|
||||
|
||||
@ -218,31 +220,27 @@ PropertyMap Ogg::XiphComment::setProperties(const PropertyMap &properties)
|
||||
{
|
||||
// check which keys are to be deleted
|
||||
StringList toRemove;
|
||||
for(auto it = d->fieldListMap.cbegin(); it != d->fieldListMap.cend(); ++it)
|
||||
if (!properties.contains(it->first))
|
||||
toRemove.append(it->first);
|
||||
for(const auto &[field, _] : std::as_const(d->fieldListMap))
|
||||
if(!properties.contains(field))
|
||||
toRemove.append(field);
|
||||
|
||||
for(auto it = toRemove.cbegin(); it != toRemove.cend(); ++it)
|
||||
removeFields(*it);
|
||||
for(const auto &field : std::as_const(toRemove))
|
||||
removeFields(field);
|
||||
|
||||
// now go through keys in \a properties and check that the values match those in the xiph comment
|
||||
PropertyMap invalid;
|
||||
for(auto it = properties.begin(); it != properties.end(); ++it)
|
||||
{
|
||||
if(!checkKey(it->first))
|
||||
invalid.insert(it->first, it->second);
|
||||
else if(!d->fieldListMap.contains(it->first) || !(it->second == d->fieldListMap[it->first])) {
|
||||
const StringList &sl = it->second;
|
||||
for(const auto &[key, sl] : properties) {
|
||||
if(!checkKey(key))
|
||||
invalid.insert(key, sl);
|
||||
else if(!d->fieldListMap.contains(key) || !(sl == d->fieldListMap[key])) {
|
||||
if(sl.isEmpty())
|
||||
// zero size string list -> remove the tag with all values
|
||||
removeFields(it->first);
|
||||
removeFields(key);
|
||||
else {
|
||||
// replace all strings in the list for the tag
|
||||
auto valueIterator = sl.begin();
|
||||
addField(it->first, *valueIterator, true);
|
||||
++valueIterator;
|
||||
for(; valueIterator != sl.end(); ++valueIterator)
|
||||
addField(it->first, *valueIterator, false);
|
||||
addField(key, *sl.begin(), true);
|
||||
for(auto it = std::next(sl.begin()); it != sl.end(); ++it)
|
||||
addField(key, *it, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -353,25 +351,20 @@ ByteVector Ogg::XiphComment::render(bool addFramingBit) const
|
||||
// std::pair<String, StringList> where the first String is the field name and
|
||||
// the StringList is the values associated with that field.
|
||||
|
||||
for(auto it = d->fieldListMap.cbegin(); it != d->fieldListMap.cend(); ++it) {
|
||||
|
||||
for(const auto &[fieldName, values] : std::as_const(d->fieldListMap)) {
|
||||
// And now iterate over the values of the current list.
|
||||
|
||||
String fieldName = (*it).first;
|
||||
const StringList values = (*it).second;
|
||||
|
||||
for(auto valuesIt = values.begin(); valuesIt != values.end(); ++valuesIt) {
|
||||
for(const auto &value : values) {
|
||||
ByteVector fieldData = fieldName.data(String::UTF8);
|
||||
fieldData.append('=');
|
||||
fieldData.append((*valuesIt).data(String::UTF8));
|
||||
fieldData.append(value.data(String::UTF8));
|
||||
|
||||
data.append(ByteVector::fromUInt(fieldData.size(), false));
|
||||
data.append(fieldData);
|
||||
}
|
||||
}
|
||||
|
||||
for(auto it = d->pictureList.cbegin(); it != d->pictureList.cend(); ++it) {
|
||||
ByteVector picture = (*it)->render().toBase64();
|
||||
for(const auto &p : std::as_const(d->pictureList)) {
|
||||
ByteVector picture = p->render().toBase64();
|
||||
data.append(ByteVector::fromUInt(picture.size() + 23, false));
|
||||
data.append("METADATA_BLOCK_PICTURE=");
|
||||
data.append(picture);
|
||||
|
||||
@ -30,6 +30,8 @@
|
||||
|
||||
#include "riffutils.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace RIFF::Info;
|
||||
|
||||
@ -199,12 +201,12 @@ ByteVector RIFF::Info::Tag::render() const
|
||||
{
|
||||
ByteVector data("INFO");
|
||||
|
||||
for(auto it = d->fieldListMap.cbegin(); it != d->fieldListMap.cend(); ++it) {
|
||||
ByteVector text = stringHandler->render(it->second);
|
||||
for(const auto &[field, list] : std::as_const(d->fieldListMap)) {
|
||||
ByteVector text = stringHandler->render(list);
|
||||
if(text.isEmpty())
|
||||
continue;
|
||||
|
||||
data.append(it->first);
|
||||
data.append(field);
|
||||
data.append(ByteVector::fromUInt(text.size() + 1, false));
|
||||
data.append(text);
|
||||
|
||||
|
||||
@ -27,6 +27,8 @@
|
||||
#include "tstringlist.h"
|
||||
#include "tpropertymap.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class Tag::TagPrivate
|
||||
@ -134,11 +136,11 @@ 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(auto it = oneValueSet.cbegin(); it != oneValueSet.cend(); ++it) {
|
||||
if(properties[*it].size() == 1)
|
||||
properties.erase(*it);
|
||||
for(const auto &entry : std::as_const(oneValueSet)) {
|
||||
if(properties[entry].size() == 1)
|
||||
properties.erase(entry);
|
||||
else
|
||||
properties[*it].erase( properties[*it].begin() );
|
||||
properties[entry].erase(properties[entry].begin());
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
@ -451,10 +451,7 @@ ByteVector &ByteVector::replace(char oldByte, char newByte)
|
||||
{
|
||||
detach();
|
||||
|
||||
for(auto it = begin(); it != end(); ++it) {
|
||||
if(*it == oldByte)
|
||||
*it = newByte;
|
||||
}
|
||||
std::replace(this->begin(), this->end(), oldByte, newByte);
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -965,7 +962,8 @@ void ByteVector::detach()
|
||||
|
||||
std::ostream &operator<<(std::ostream &s, const TagLib::ByteVector &v)
|
||||
{
|
||||
for(unsigned int i = 0; i < v.size(); i++)
|
||||
s << v[i];
|
||||
for(const auto &byte : v) {
|
||||
s << byte;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -85,12 +85,9 @@ ByteVector ByteVectorList::toByteVector(const ByteVector &separator) const
|
||||
{
|
||||
ByteVector v;
|
||||
|
||||
auto it = begin();
|
||||
|
||||
while(it != end()) {
|
||||
for(auto it = begin(); it != end(); ++it) {
|
||||
v.append(*it);
|
||||
it++;
|
||||
if(it != end())
|
||||
if(std::next(it) != end())
|
||||
v.append(separator);
|
||||
}
|
||||
|
||||
|
||||
@ -27,6 +27,8 @@
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
#include <utility>
|
||||
|
||||
class PropertyMap::PropertyMapPrivate
|
||||
{
|
||||
public:
|
||||
@ -49,7 +51,7 @@ PropertyMap::PropertyMap(const PropertyMap &m) :
|
||||
PropertyMap::PropertyMap(const SimplePropertyMap &m) :
|
||||
d(std::make_unique<PropertyMapPrivate>())
|
||||
{
|
||||
for(auto [key, value] : m) {
|
||||
for(const auto &[key, value] : m) {
|
||||
if(!key.isEmpty())
|
||||
insert(key.upper(), value);
|
||||
else
|
||||
@ -106,15 +108,15 @@ PropertyMap &PropertyMap::erase(const String &key)
|
||||
|
||||
PropertyMap &PropertyMap::erase(const PropertyMap &other)
|
||||
{
|
||||
for(auto it = other.begin(); it != other.end(); ++it)
|
||||
erase(it->first);
|
||||
for(const auto &[property, _] : other)
|
||||
erase(property);
|
||||
return *this;
|
||||
}
|
||||
|
||||
PropertyMap &PropertyMap::merge(const PropertyMap &other)
|
||||
{
|
||||
for(auto it = other.begin(); it != other.end(); ++it)
|
||||
insert(it->first, it->second);
|
||||
for(const auto &[property, value] : other)
|
||||
insert(property, value);
|
||||
d->unsupported.append(other.d->unsupported);
|
||||
return *this;
|
||||
}
|
||||
@ -137,14 +139,14 @@ StringList &PropertyMap::operator[](const String &key)
|
||||
|
||||
bool PropertyMap::operator==(const PropertyMap &other) const
|
||||
{
|
||||
for(auto it = other.begin(); it != other.end(); ++it) {
|
||||
auto thisFind = find(it->first);
|
||||
if( thisFind == end() || (thisFind->second != it->second) )
|
||||
for(const auto &[property, value] : other) {
|
||||
auto thisFind = find(property);
|
||||
if(thisFind == end() || (thisFind->second != value))
|
||||
return false;
|
||||
}
|
||||
for(auto it = begin(); it != end(); ++it) {
|
||||
auto otherFind = other.find(it->first);
|
||||
if( otherFind == other.end() || (otherFind->second != it->second) )
|
||||
for(const auto &[property, value] : *this) {
|
||||
auto otherFind = other.find(property);
|
||||
if(otherFind == other.end() || (otherFind->second != value))
|
||||
return false;
|
||||
}
|
||||
return d->unsupported == other.d->unsupported;
|
||||
@ -159,8 +161,8 @@ String PropertyMap::toString() const
|
||||
{
|
||||
String ret;
|
||||
|
||||
for(auto it = begin(); it != end(); ++it)
|
||||
ret += it->first+"="+it->second.toString(", ") + "\n";
|
||||
for(const auto &[property, value] : *this)
|
||||
ret += property + "=" + value.toString(", ") + "\n";
|
||||
if(!d->unsupported.isEmpty())
|
||||
ret += "Unsupported Data: " + d->unsupported.toString(", ") + "\n";
|
||||
return ret;
|
||||
@ -169,9 +171,9 @@ String PropertyMap::toString() const
|
||||
void PropertyMap::removeEmpty()
|
||||
{
|
||||
PropertyMap m;
|
||||
for(auto it = cbegin(); it != cend(); ++it) {
|
||||
if(!it->second.isEmpty())
|
||||
m.insert(it->first, it->second);
|
||||
for(const auto &[property, value] : std::as_const(*this)) {
|
||||
if(!value.isEmpty())
|
||||
m.insert(property, value);
|
||||
}
|
||||
*this = m;
|
||||
}
|
||||
|
||||
@ -376,11 +376,11 @@ String String::upper() const
|
||||
String s;
|
||||
s.d->data.reserve(size());
|
||||
|
||||
for(ConstIterator it = begin(); it != end(); ++it) {
|
||||
if(*it >= 'a' && *it <= 'z')
|
||||
s.d->data.push_back(*it + 'A' - 'a');
|
||||
for(wchar_t c : *this) {
|
||||
if(c >= 'a' && c <= 'z')
|
||||
s.d->data.push_back(c + 'A' - 'a');
|
||||
else
|
||||
s.d->data.push_back(*it);
|
||||
s.d->data.push_back(c);
|
||||
}
|
||||
|
||||
return s;
|
||||
@ -410,8 +410,9 @@ ByteVector String::data(Type t) const
|
||||
ByteVector v(size(), 0);
|
||||
char *p = v.data();
|
||||
|
||||
for(ConstIterator it = begin(); it != end(); ++it)
|
||||
*p++ = static_cast<char>(*it);
|
||||
for(wchar_t c : *this) {
|
||||
*p++ = static_cast<char>(c);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
@ -441,9 +442,9 @@ ByteVector String::data(Type t) const
|
||||
*p++ = '\xff';
|
||||
*p++ = '\xfe';
|
||||
|
||||
for(ConstIterator it = begin(); it != end(); ++it) {
|
||||
*p++ = static_cast<char>(*it & 0xff);
|
||||
*p++ = static_cast<char>(*it >> 8);
|
||||
for(wchar_t c : *this) {
|
||||
*p++ = static_cast<char>(c & 0xff);
|
||||
*p++ = static_cast<char>(c >> 8);
|
||||
}
|
||||
|
||||
return v;
|
||||
@ -453,9 +454,9 @@ ByteVector String::data(Type t) const
|
||||
ByteVector v(size() * 2, 0);
|
||||
char *p = v.data();
|
||||
|
||||
for(ConstIterator it = begin(); it != end(); ++it) {
|
||||
*p++ = static_cast<char>(*it >> 8);
|
||||
*p++ = static_cast<char>(*it & 0xff);
|
||||
for(wchar_t c : *this) {
|
||||
*p++ = static_cast<char>(c >> 8);
|
||||
*p++ = static_cast<char>(c & 0xff);
|
||||
}
|
||||
|
||||
return v;
|
||||
@ -465,9 +466,9 @@ ByteVector String::data(Type t) const
|
||||
ByteVector v(size() * 2, 0);
|
||||
char *p = v.data();
|
||||
|
||||
for(ConstIterator it = begin(); it != end(); ++it) {
|
||||
*p++ = static_cast<char>(*it & 0xff);
|
||||
*p++ = static_cast<char>(*it >> 8);
|
||||
for(wchar_t c : *this) {
|
||||
*p++ = static_cast<char>(c & 0xff);
|
||||
*p++ = static_cast<char>(c >> 8);
|
||||
}
|
||||
|
||||
return v;
|
||||
|
||||
@ -77,8 +77,8 @@ StringList::StringList(const String &s)
|
||||
|
||||
StringList::StringList(const ByteVectorList &bl, String::Type t)
|
||||
{
|
||||
for(auto i = bl.begin(); i != bl.end(); i++) {
|
||||
append(String(*i, t));
|
||||
for(const auto &byte : bl) {
|
||||
append(String(byte, t));
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,13 +88,9 @@ String StringList::toString(const String &separator) const
|
||||
{
|
||||
String s;
|
||||
|
||||
auto it = begin();
|
||||
auto itEnd = end();
|
||||
|
||||
while(it != itEnd) {
|
||||
for(auto it = begin(); it != end(); ++it) {
|
||||
s += *it;
|
||||
it++;
|
||||
if(it != itEnd)
|
||||
if(std::next(it) != end())
|
||||
s += separator;
|
||||
}
|
||||
|
||||
|
||||
@ -30,8 +30,9 @@
|
||||
#include "modfileprivate.h"
|
||||
#include "tpropertymap.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace XM;
|
||||
@ -319,9 +320,8 @@ public:
|
||||
unsigned int size() const override
|
||||
{
|
||||
unsigned int size = 0;
|
||||
for(auto i = m_readers.begin();
|
||||
i != m_readers.end(); ++ i) {
|
||||
size += (*i)->size();
|
||||
for(const auto &reader : m_readers) {
|
||||
size += reader->size();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
@ -329,9 +329,10 @@ public:
|
||||
unsigned int read(TagLib::File &file, unsigned int limit) override
|
||||
{
|
||||
unsigned int sumcount = 0;
|
||||
for(auto i = m_readers.cbegin();
|
||||
limit > 0 && i != m_readers.cend(); ++ i) {
|
||||
unsigned int count = (*i)->read(file, limit);
|
||||
for(const auto &reader : std::as_const(m_readers)) {
|
||||
if(limit == 0)
|
||||
break;
|
||||
unsigned int count = reader->read(file, limit);
|
||||
limit -= count;
|
||||
sumcount += count;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user