aboutsummaryrefslogtreecommitdiffstats
path: root/src/tag/Tag.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/tag/Tag.hxx')
-rw-r--r--src/tag/Tag.hxx114
1 files changed, 74 insertions, 40 deletions
diff --git a/src/tag/Tag.hxx b/src/tag/Tag.hxx
index 5846e7a9d..f1d3d5767 100644
--- a/src/tag/Tag.hxx
+++ b/src/tag/Tag.hxx
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2013 The Music Player Daemon Project
+ * Copyright (C) 2003-2014 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -20,11 +20,13 @@
#ifndef MPD_TAG_HXX
#define MPD_TAG_HXX
-#include "TagType.h"
-#include "TagItem.hxx"
+#include "TagType.h" // IWYU pragma: export
+#include "TagItem.hxx" // IWYU pragma: export
+#include "Chrono.hxx"
#include "Compiler.h"
#include <algorithm>
+#include <iterator>
#include <stddef.h>
@@ -34,12 +36,10 @@
*/
struct Tag {
/**
- * The duration of the song (in seconds). A value of zero
- * means that the length is unknown. If the duration is
- * really between zero and one second, you should round up to
- * 1.
+ * The duration of the song. A negative value means that the
+ * length is unknown.
*/
- int time;
+ SignedSongTime duration;
/**
* Does this file have an embedded playlist (e.g. embedded CUE
@@ -47,23 +47,23 @@ struct Tag {
*/
bool has_playlist;
+ /** the total number of tag items in the #items array */
+ unsigned short num_items;
+
/** an array of tag items */
TagItem **items;
- /** the total number of tag items in the #items array */
- unsigned num_items;
-
/**
* Create an empty tag.
*/
- Tag():time(-1), has_playlist(false),
- items(nullptr), num_items(0) {}
+ Tag():duration(SignedSongTime::Negative()), has_playlist(false),
+ num_items(0), items(nullptr) {}
Tag(const Tag &other);
Tag(Tag &&other)
- :time(other.time), has_playlist(other.has_playlist),
- items(other.items), num_items(other.num_items) {
+ :duration(other.duration), has_playlist(other.has_playlist),
+ num_items(other.num_items), items(other.items) {
other.items = nullptr;
other.num_items = 0;
}
@@ -71,12 +71,14 @@ struct Tag {
/**
* Free the tag object and all its items.
*/
- ~Tag();
+ ~Tag() {
+ Clear();
+ }
Tag &operator=(const Tag &other) = delete;
Tag &operator=(Tag &&other) {
- time = other.time;
+ duration = other.duration;
has_playlist = other.has_playlist;
std::swap(items, other.items);
std::swap(num_items, other.num_items);
@@ -84,8 +86,8 @@ struct Tag {
}
/**
- * Returns true if the tag contains no items. This ignores the "time"
- * attribute.
+ * Returns true if the tag contains no items. This ignores
+ * the "duration" attribute.
*/
bool IsEmpty() const {
return num_items == 0;
@@ -95,7 +97,7 @@ struct Tag {
* Returns true if the tag contains any information.
*/
bool IsDefined() const {
- return !IsEmpty() || time >= 0;
+ return !IsEmpty() || !duration.IsNegative();
}
/**
@@ -104,24 +106,6 @@ struct Tag {
void Clear();
/**
- * Appends a new tag item.
- *
- * @param type the type of the new tag item
- * @param value the value of the tag item (not null-terminated)
- * @param len the length of #value
- */
- void AddItem(TagType type, const char *value, size_t len);
-
- /**
- * Appends a new tag item.
- *
- * @param tag the #tag object
- * @param type the type of the new tag item
- * @param value the value of the tag item (null-terminated)
- */
- void AddItem(TagType type, const char *value);
-
- /**
* Merges the data from two tags. If both tags share data for the
* same TagType, only data from "add" is used.
*
@@ -153,8 +137,58 @@ struct Tag {
gcc_pure
bool HasType(TagType type) const;
-private:
- void AddItemInternal(TagType type, const char *value, size_t len);
+ class const_iterator {
+ friend struct Tag;
+ const TagItem *const*cursor;
+
+ constexpr const_iterator(const TagItem *const*_cursor)
+ :cursor(_cursor) {}
+
+ public:
+ constexpr const TagItem &operator*() const {
+ return **cursor;
+ }
+
+ constexpr const TagItem *operator->() const {
+ return *cursor;
+ }
+
+ const_iterator &operator++() {
+ ++cursor;
+ return *this;
+ }
+
+ const_iterator operator++(int) {
+ auto result = cursor++;
+ return const_iterator{result};
+ }
+
+ const_iterator &operator--() {
+ --cursor;
+ return *this;
+ }
+
+ const_iterator operator--(int) {
+ auto result = cursor--;
+ return const_iterator{result};
+ }
+
+ constexpr bool operator==(const_iterator other) const {
+ return cursor == other.cursor;
+ }
+
+ constexpr bool operator!=(const_iterator other) const {
+ return cursor != other.cursor;
+ }
+ };
+
+ const_iterator begin() const {
+ return const_iterator{items};
+ }
+
+ const_iterator end() const {
+ return const_iterator{items + num_items};
+ }
};
/**