Sayonara Player
MP4Frame.h
1/* MP4Frame.h */
2
3/* Copyright (C) 2011-2020 Michael Lugmair (Lucio Carreras)
4 *
5 * This file is part of sayonara player
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#ifndef SAYONARA_ABSTRACT_MP4_FRAME_H
22#define SAYONARA_ABSTRACT_MP4_FRAME_H
23
24#include "Utils/Tagging/AbstractFrame.h"
25#include "Utils/Algorithm.h"
26
27#include <QString>
28
29#include <taglib/tag.h>
30#include <taglib/tstringlist.h>
31#include <taglib/mp4tag.h>
32#include <taglib/tpropertymap.h>
33
34#include <algorithm>
35#include <optional>
36
37namespace MP4
38{
39 template<typename Model_t>
40 class MP4Frame :
41 protected Tagging::AbstractFrame<TagLib::MP4::Tag>
42 {
43 protected:
44 TagLib::MP4::ItemMap::ConstIterator findKey(const TagLib::MP4::ItemMap& itemMap) const
45 {
46 return std::find_if(itemMap.begin(), itemMap.end(), [&](const auto& itemList) {
47 const auto convertedString = Tagging::convertString(itemList.first);
48 return (convertedString.compare(key(), Qt::CaseInsensitive) == 0);
49 });
50 }
51
52 void eraseAllFromTag(TagLib::MP4::Tag* tag, const QString& key)
53 {
54 const auto taglibKey = Tagging::convertString(key);
55 while(tag->contains(taglibKey))
56 {
57 tag->removeItem(taglibKey);
58 }
59 }
60
61 virtual std::optional<Model_t> mapItemToData(const TagLib::MP4::Item& item) const = 0;
62 virtual std::optional<TagLib::MP4::Item> mapDataToItem(const Model_t& model) = 0;
63
64 public:
65 MP4Frame(TagLib::MP4::Tag* tag, const QString& identifier) :
67
68 virtual ~MP4Frame() = default;
69
70 bool read(Model_t& data) const
71 {
72 if(!tag())
73 {
74 return false;
75 }
76
77 const auto& itemMap = tag()->itemMap();
78 const auto it = findKey(itemMap);
79 if(it != itemMap.end() && it->second.isValid())
80 {
81 const auto optionalData = mapItemToData(it->second);
82 if(optionalData.has_value())
83 {
84 data = optionalData.value();
85 return true;
86 }
87 }
88
89 return false;
90 }
91
92 bool write(const Model_t& data)
93 {
94 if(!tag())
95 {
96 return false;
97 }
98
99 eraseAllFromTag(tag(), key());
100
101 const auto item = mapDataToItem(data);
102 if(item.has_value() && item.value().isValid())
103 {
104 tag()->setItem(tagKey(), *item);
105 }
106
107 return item.has_value();
108 }
109
110 bool isFrameAvailable() const
111 {
112 if(!tag())
113 {
114 return false;
115 }
116
117 const auto& itemMap = tag()->itemMap();
118 return (findKey(itemMap) != itemMap.end());
119 }
120 };
121}
122
123#endif // SAYONARA_ABSTRACT_MP4_FRAME_H
Definition: MP4Frame.h:42
Definition: AbstractFrame.h:54