Sayonara Player
ID3v2Frame.h
1 /* AbstractFrame.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_ID3V2_FRAME_H
22 #define SAYONARA_ID3V2_FRAME_H
23 
24 #include "Utils/Tagging/AbstractFrame.h"
25 
26 #include <QString>
27 
28 #include <taglib/fileref.h>
29 #include <taglib/mpegfile.h>
30 #include <taglib/id3v2tag.h>
31 #include <taglib/id3v2frame.h>
32 
33 #include <optional>
34 
35 namespace ID3v2
36 {
37  template<typename ModelType_t, typename FrameType_t>
38  class ID3v2Frame :
39  protected Tagging::AbstractFrame<TagLib::ID3v2::Tag>
40  {
41  protected:
42  FrameType_t* mFrame {nullptr};
43 
44  protected:
45  virtual TagLib::ID3v2::Frame* createId3v2Frame() = 0;
46 
47  virtual void mapDataToFrame(const ModelType_t& model, FrameType_t* frame) = 0;
48  virtual std::optional<ModelType_t> mapFrameToData(const FrameType_t* frame) const = 0;
49 
50  public:
51  ID3v2Frame(TagLib::ID3v2::Tag* tag, const char* four) :
53  {
54  const auto byteVector = TagLib::ByteVector(four, 4);
55  const auto frameListMap = tag->frameListMap();
56  const auto frameList = frameListMap[byteVector];
57  if(!frameList.isEmpty())
58  {
59  mFrame = dynamic_cast<FrameType_t*>(frameList.front());
60  }
61  }
62 
63  virtual ~ID3v2Frame() = default;
64 
65  virtual bool read(ModelType_t& data) const
66  {
67  if(mFrame)
68  {
69  if(const auto optData = mapFrameToData(mFrame); optData.has_value())
70  {
71  data = optData.value();
72  return true;
73  }
74  }
75 
76  return false;
77  }
78 
79  virtual bool write(const ModelType_t& data)
80  {
81  if(!tag())
82  {
83  return false;
84  }
85 
86  auto created = false;
87  if(!mFrame)
88  {
89  mFrame = dynamic_cast<FrameType_t*>(createId3v2Frame());
90  if(!mFrame)
91  {
92  return false;
93  }
94 
95  created = true;
96  }
97 
98  mapDataToFrame(data, mFrame);
99 
100  if(created)
101  {
102  tag()->addFrame(mFrame);
103  }
104 
105  return true;
106  }
107 
108  bool isFrameAvailable() const
109  {
110  return (mFrame != nullptr);
111  }
112 
113  FrameType_t* frame()
114  {
115  return mFrame;
116  }
117  };
118 }
119 
120 #endif // SAYONARA_ID3V2_FRAME_H
Definition: ID3v2Frame.h:40
Definition: AbstractFrame.h:54