Tag Parser  6.3.0
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
genericcontainer.h
Go to the documentation of this file.
1 #ifndef MEDIA_GENERICCONTAINER_H
2 #define MEDIA_GENERICCONTAINER_H
3 
4 #include "./abstractcontainer.h"
5 
6 #include <algorithm>
7 #include <memory>
8 #include <vector>
9 #include <memory>
10 
11 namespace Media {
12 
23 template <class FileInfoType, class TagType, class TrackType, class ElementType>
25 {
26  friend FileInfoType;
27 
28 public:
29  GenericContainer(FileInfoType &fileInfo, uint64 startOffset);
31 
32  void validateElementStructure(NotificationList &gatheredNotifications, uint64 *paddingSize = nullptr);
33  FileInfoType &fileInfo() const;
34  ElementType *firstElement() const;
35  const std::vector<std::unique_ptr<ElementType> > &additionalElements() const;
36  std::vector<std::unique_ptr<ElementType> > &additionalElements();
37  TagType *tag(std::size_t index);
38  std::size_t tagCount() const;
39  TrackType *track(std::size_t index);
40  std::size_t trackCount() const;
41  const std::vector<std::unique_ptr<TagType> > &tags() const;
42  std::vector<std::unique_ptr<TagType> > &tags();
43  const std::vector<std::unique_ptr<TrackType> > &tracks() const;
44  std::vector<std::unique_ptr<TrackType> > &tracks();
45 
46  TagType *createTag(const TagTarget &target = TagTarget());
47  bool removeTag(Tag *tag);
48  void removeAllTags();
49  bool addTrack(TrackType *track);
50  bool removeTrack(AbstractTrack *track);
51  void removeAllTracks();
52  void reset();
53 
54  typedef FileInfoType fileInfoType;
55  typedef TagType tagType;
57  typedef ElementType elementType;
58 
59 protected:
60  std::unique_ptr<ElementType> m_firstElement;
61  std::vector<std::unique_ptr<ElementType> > m_additionalElements;
62  std::vector<std::unique_ptr<TagType> > m_tags;
63  std::vector<std::unique_ptr<TrackType> > m_tracks;
64 
65 private:
66  FileInfoType *m_fileInfo;
67 };
68 
72 template <class FileInfoType, class TagType, class TrackType, class ElementType>
74  AbstractContainer(fileInfo.stream(), startOffset),
75  m_fileInfo(&fileInfo)
76 {}
77 
84 template <class FileInfoType, class TagType, class TrackType, class ElementType>
86 {}
87 
98 template <class FileInfoType, class TagType, class TrackType, class ElementType>
100 {
101  parseHeader();
102  if(m_firstElement) {
103  m_firstElement->validateSubsequentElementStructure(gatheredNotifications, paddingSize);
104  }
105 }
106 
112 template <class FileInfoType, class TagType, class TrackType, class ElementType>
114 {
115  return *m_fileInfo;
116 }
117 
130 template <class FileInfoType, class TagType, class TrackType, class ElementType>
132 {
133  return m_firstElement.get();
134 }
135 
143 template <class FileInfoType, class TagType, class TrackType, class ElementType>
144 inline const std::vector<std::unique_ptr<ElementType> > &GenericContainer<FileInfoType, TagType, TrackType, ElementType>::additionalElements() const
145 {
146  return m_additionalElements;
147 }
148 
156 template <class FileInfoType, class TagType, class TrackType, class ElementType>
158 {
159  return m_additionalElements;
160 }
161 
162 template <class FileInfoType, class TagType, class TrackType, class ElementType>
164 {
165  return m_tags[index].get();
166 }
167 
168 template <class FileInfoType, class TagType, class TrackType, class ElementType>
170 {
171  return m_tags.size();
172 }
173 
174 template <class FileInfoType, class TagType, class TrackType, class ElementType>
176 {
177  return m_tracks[index].get();
178 }
179 
180 template <class FileInfoType, class TagType, class TrackType, class ElementType>
182 {
183  return m_tracks.size();
184 }
185 
195 template <class FileInfoType, class TagType, class TrackType, class ElementType>
196 inline const std::vector<std::unique_ptr<TagType> > &GenericContainer<FileInfoType, TagType, TrackType, ElementType>::tags() const
197 {
198  return m_tags;
199 }
200 
210 template <class FileInfoType, class TagType, class TrackType, class ElementType>
211 inline std::vector<std::unique_ptr<TagType> > &GenericContainer<FileInfoType, TagType, TrackType, ElementType>::tags()
212 {
213  return m_tags;
214 }
215 
225 template <class FileInfoType, class TagType, class TrackType, class ElementType>
226 inline const std::vector<std::unique_ptr<TrackType> > &GenericContainer<FileInfoType, TagType, TrackType, ElementType>::tracks() const
227 {
228  return m_tracks;
229 }
230 
240 template <class FileInfoType, class TagType, class TrackType, class ElementType>
241 inline std::vector<std::unique_ptr<TrackType> > &GenericContainer<FileInfoType, TagType, TrackType, ElementType>::tracks()
242 {
243  return m_tracks;
244 }
245 
246 template <class FileInfoType, class TagType, class TrackType, class ElementType>
248 {
249  // check whether a tag matching the specified target is already assigned
250  if(!m_tags.empty()) {
251  if(!target.isEmpty() && m_tags.front()->supportsTarget()) {
252  for(auto &tag : m_tags) {
253  if(tag->target() == target) {
254  return tag.get();
255  }
256  }
257  } else {
258  return m_tags.front().get();
259  }
260  }
261 
262  // a new tag must be created
263  m_tags.emplace_back(std::make_unique<TagType>());
264  auto &tag = m_tags.back();
265  tag->setTarget(target);
266  return tag.get();
267 }
268 
269 template <class FileInfoType, class TagType, class TrackType, class ElementType>
271 {
272  if(auto size = m_tags.size()) {
273  m_tags.erase(std::remove_if(m_tags.begin(), m_tags.end(), [tag] (const std::unique_ptr<TagType> &existingTag) -> bool {
274  return static_cast<Tag *>(existingTag.get()) == tag;
275  }), m_tags.end());
276  return size != m_tags.size();
277  }
278  return false;
279 }
280 
281 template <class FileInfoType, class TagType, class TrackType, class ElementType>
283 {
284  m_tags.clear();
285 }
286 
303 template <class FileInfoType, class TagType, class TrackType, class ElementType>
305 {
306  if(areTracksParsed() && supportsTrackModifications()) {
307  // ensure ID is unique
308  auto id = track->id();
309  ensureIdIsUnique:
310  for(const auto &track : m_tracks) {
311  if(track->id() == id) {
312  ++id;
313  goto ensureIdIsUnique;
314  }
315  }
316  track->setId(id);
317 
318  m_tracks.emplace_back(track);
319  return m_tracksAltered = true;
320  }
321  return false;
322 }
323 
324 template <class FileInfoType, class TagType, class TrackType, class ElementType>
326 {
327  bool removed = false;
328  if(areTracksParsed() && supportsTrackModifications() && !m_tracks.empty()) {
329  for(auto i = m_tracks.end() - 1, begin = m_tracks.begin(); ; --i) {
330  if(static_cast<AbstractTrack *>(i->get()) == track) {
331  i->release();
332  m_tracks.erase(i);
333  removed = true;
334  }
335  if(i == begin) {
336  break;
337  }
338  }
339  if(removed) {
340  m_tracksAltered = true;
341  }
342  }
343  return removed;
344 }
345 
346 template <class FileInfoType, class TagType, class TrackType, class ElementType>
348 {
349  if(areTracksParsed() && supportsTrackModifications() && m_tracks.size()) {
350  m_tracks.clear();
351  m_tracksAltered = true;
352  }
353 }
354 
355 template <class FileInfoType, class TagType, class TrackType, class ElementType>
357 {
358  AbstractContainer::reset();
359  m_firstElement.reset();
360  m_additionalElements.clear();
361  m_tracks.clear();
362  m_tags.clear();
363 }
364 
365 } // namespace Media
366 
367 #endif // MEDIA_GENERICCONTAINER_H
bool isEmpty() const
Returns an indication whether the target is empty.
Definition: tagtarget.h:177
The GenericContainer class helps parsing header, track, tag and chapter information of a file...
std::vector< std::unique_ptr< TrackType > > m_tracks
TrackType
Specifies the track type.
Definition: abstracttrack.h:28
The AbstractTrack class parses and stores technical information about video, audio and other kinds of...
Definition: abstracttrack.h:40
std::vector< std::unique_ptr< ElementType > > m_additionalElements
The Tag class is used to store, read and write tag information.
Definition: tag.h:98
GenericContainer(FileInfoType &fileInfo, uint64 startOffset)
Constructs a new container for the specified fileInfo at the specified startOffset.
The AbstractContainer class provides an interface and common functionality to parse and make a certai...
std::vector< std::unique_ptr< TagType > > m_tags
std::list< Notification > NotificationList
Definition: notification.h:39
TagType
Specifies the tag type.
Definition: tag.h:21
The TagTarget class specifies the target of a tag.
Definition: tagtarget.h:31
Contains all classes and functions of the TagInfo library.
Definition: exceptions.h:9
#define TAG_PARSER_EXPORT
Marks the symbol to be exported by the tagparser library.
std::unique_ptr< ElementType > m_firstElement