tag: convert to C++
This commit is contained in:
parent
6a9ab8bc0e
commit
06f898cc12
|
@ -76,7 +76,6 @@ mpd_headers = \
|
|||
src/replay_gain_info.h \
|
||||
src/TimePrint.cxx src/TimePrint.hxx \
|
||||
src/stats.h \
|
||||
src/tag.h \
|
||||
src/tag_internal.h \
|
||||
src/Timer.hxx \
|
||||
src/mpd_error.h
|
||||
|
@ -217,7 +216,7 @@ src_mpd_SOURCES = \
|
|||
src/StateFile.cxx src/StateFile.hxx \
|
||||
src/Stats.cxx \
|
||||
src/TagType.h \
|
||||
src/Tag.cxx \
|
||||
src/Tag.cxx src/Tag.hxx \
|
||||
src/TagTable.hxx \
|
||||
src/TagNames.c \
|
||||
src/TagPool.cxx src/TagPool.hxx \
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "MessageCommands.hxx"
|
||||
#include "OtherCommands.hxx"
|
||||
#include "Permission.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "protocol/Result.hxx"
|
||||
#include "Client.hxx"
|
||||
#include "util/Tokenizer.hxx"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "config.h"
|
||||
#include "ApeTag.hxx"
|
||||
#include "ApeLoader.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "TagTable.hxx"
|
||||
#include "TagHandler.hxx"
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "CrossFade.hxx"
|
||||
#include "MusicChunk.hxx"
|
||||
#include "audio_format.h"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "DatabaseSelection.hxx"
|
||||
#include "CommandError.hxx"
|
||||
#include "ClientInternal.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "SongFilter.hxx"
|
||||
#include "protocol/Result.hxx"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "DatabaseHelpers.hxx"
|
||||
#include "DatabasePlugin.hxx"
|
||||
#include "Song.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <functional>
|
||||
#include <set>
|
||||
|
@ -39,7 +39,7 @@ typedef std::set<const char *, StringLess> StringSet;
|
|||
static bool
|
||||
CollectTags(StringSet &set, enum tag_type tag_type, Song &song)
|
||||
{
|
||||
struct tag *tag = song.tag;
|
||||
Tag *tag = song.tag;
|
||||
if (tag == nullptr)
|
||||
return true;
|
||||
|
||||
|
@ -79,13 +79,13 @@ VisitUniqueTags(const Database &db, const DatabaseSelection &selection,
|
|||
|
||||
static void
|
||||
StatsVisitTag(DatabaseStats &stats, StringSet &artists, StringSet &albums,
|
||||
const struct tag &tag)
|
||||
const Tag &tag)
|
||||
{
|
||||
if (tag.time > 0)
|
||||
stats.total_duration += tag.time;
|
||||
|
||||
for (unsigned i = 0; i < tag.num_items; ++i) {
|
||||
const struct tag_item &item = *tag.items[i];
|
||||
const TagItem &item = *tag.items[i];
|
||||
|
||||
switch (item.type) {
|
||||
case TAG_ARTIST:
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "TimePrint.hxx"
|
||||
#include "Directory.hxx"
|
||||
#include "Client.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "Song.hxx"
|
||||
#include "DatabaseGlue.hxx"
|
||||
#include "DatabasePlugin.hxx"
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include "Song.hxx"
|
||||
#include "TextFile.hxx"
|
||||
#include "TagInternal.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
#define G_LOG_DOMAIN "decoder"
|
||||
|
@ -312,7 +313,7 @@ decoder_timestamp(struct decoder *decoder, double t)
|
|||
* (decoder.chunk) if there is one.
|
||||
*/
|
||||
static enum decoder_command
|
||||
do_send_tag(struct decoder *decoder, const struct tag *tag)
|
||||
do_send_tag(struct decoder *decoder, const Tag &tag)
|
||||
{
|
||||
struct music_chunk *chunk;
|
||||
|
||||
|
@ -331,14 +332,14 @@ do_send_tag(struct decoder *decoder, const struct tag *tag)
|
|||
return decoder->dc->command;
|
||||
}
|
||||
|
||||
chunk->tag = tag_dup(tag);
|
||||
chunk->tag = new Tag(tag);
|
||||
return DECODE_COMMAND_NONE;
|
||||
}
|
||||
|
||||
static bool
|
||||
update_stream_tag(struct decoder *decoder, struct input_stream *is)
|
||||
{
|
||||
struct tag *tag;
|
||||
Tag *tag;
|
||||
|
||||
tag = is != NULL
|
||||
? input_stream_lock_tag(is)
|
||||
|
@ -353,9 +354,7 @@ update_stream_tag(struct decoder *decoder, struct input_stream *is)
|
|||
decoder->song_tag = NULL;
|
||||
}
|
||||
|
||||
if (decoder->stream_tag != NULL)
|
||||
tag_free(decoder->stream_tag);
|
||||
|
||||
delete decoder->stream_tag;
|
||||
decoder->stream_tag = tag;
|
||||
return true;
|
||||
}
|
||||
|
@ -387,15 +386,13 @@ decoder_data(struct decoder *decoder,
|
|||
if (update_stream_tag(decoder, is)) {
|
||||
if (decoder->decoder_tag != NULL) {
|
||||
/* merge with tag from decoder plugin */
|
||||
struct tag *tag;
|
||||
|
||||
tag = tag_merge(decoder->decoder_tag,
|
||||
decoder->stream_tag);
|
||||
cmd = do_send_tag(decoder, tag);
|
||||
tag_free(tag);
|
||||
Tag *tag = Tag::Merge(*decoder->decoder_tag,
|
||||
*decoder->stream_tag);
|
||||
cmd = do_send_tag(decoder, *tag);
|
||||
delete tag;
|
||||
} else
|
||||
/* send only the stream tag */
|
||||
cmd = do_send_tag(decoder, decoder->stream_tag);
|
||||
cmd = do_send_tag(decoder, *decoder->stream_tag);
|
||||
|
||||
if (cmd != DECODE_COMMAND_NONE)
|
||||
return cmd;
|
||||
|
@ -474,7 +471,7 @@ decoder_data(struct decoder *decoder,
|
|||
|
||||
enum decoder_command
|
||||
decoder_tag(G_GNUC_UNUSED struct decoder *decoder, struct input_stream *is,
|
||||
const struct tag *tag)
|
||||
const Tag *tag)
|
||||
{
|
||||
G_GNUC_UNUSED const struct decoder_control *dc = decoder->dc;
|
||||
enum decoder_command cmd;
|
||||
|
@ -485,9 +482,8 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder, struct input_stream *is,
|
|||
|
||||
/* save the tag */
|
||||
|
||||
if (decoder->decoder_tag != NULL)
|
||||
tag_free(decoder->decoder_tag);
|
||||
decoder->decoder_tag = tag_dup(tag);
|
||||
delete decoder->decoder_tag;
|
||||
decoder->decoder_tag = new Tag(*tag);
|
||||
|
||||
/* check for a new stream tag */
|
||||
|
||||
|
@ -505,14 +501,15 @@ decoder_tag(G_GNUC_UNUSED struct decoder *decoder, struct input_stream *is,
|
|||
|
||||
if (decoder->stream_tag != NULL) {
|
||||
/* merge with tag from input stream */
|
||||
struct tag *merged;
|
||||
Tag *merged;
|
||||
|
||||
merged = tag_merge(decoder->stream_tag, decoder->decoder_tag);
|
||||
cmd = do_send_tag(decoder, merged);
|
||||
tag_free(merged);
|
||||
merged = Tag::Merge(*decoder->stream_tag,
|
||||
*decoder->decoder_tag);
|
||||
cmd = do_send_tag(decoder, *merged);
|
||||
delete merged;
|
||||
} else
|
||||
/* send only the decoder tag */
|
||||
cmd = do_send_tag(decoder, tag);
|
||||
cmd = do_send_tag(decoder, *tag);
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "DecoderPlugin.hxx"
|
||||
#include "input_stream.h"
|
||||
#include "replay_gain_info.h"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "audio_format.h"
|
||||
#include "conf.h"
|
||||
|
||||
|
@ -142,7 +142,7 @@ decoder_data(struct decoder *decoder, struct input_stream *is,
|
|||
*/
|
||||
enum decoder_command
|
||||
decoder_tag(struct decoder *decoder, struct input_stream *is,
|
||||
const struct tag *tag);
|
||||
const Tag *tag);
|
||||
|
||||
/**
|
||||
* Set replay gain values for the following chunks.
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <glib.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
struct DecoderBuffer {
|
||||
struct decoder *decoder;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "MusicPipe.hxx"
|
||||
#include "MusicBuffer.hxx"
|
||||
#include "MusicChunk.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
@ -32,14 +32,9 @@ decoder::~decoder()
|
|||
/* caller must flush the chunk */
|
||||
assert(chunk == nullptr);
|
||||
|
||||
if (song_tag != nullptr)
|
||||
tag_free(song_tag);
|
||||
|
||||
if (stream_tag != nullptr)
|
||||
tag_free(stream_tag);
|
||||
|
||||
if (decoder_tag != nullptr)
|
||||
tag_free(decoder_tag);
|
||||
delete song_tag;
|
||||
delete stream_tag;
|
||||
delete decoder_tag;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "replay_gain_info.h"
|
||||
|
||||
struct input_stream;
|
||||
struct Tag;
|
||||
|
||||
struct decoder {
|
||||
struct decoder_control *dc;
|
||||
|
@ -62,13 +63,13 @@ struct decoder {
|
|||
* files, because we expect the stream server to send us a new
|
||||
* tag each time we play it.
|
||||
*/
|
||||
struct tag *song_tag;
|
||||
Tag *song_tag;
|
||||
|
||||
/** the last tag received from the stream */
|
||||
struct tag *stream_tag;
|
||||
Tag *stream_tag;
|
||||
|
||||
/** the last tag received from the decoder plugin */
|
||||
struct tag *decoder_tag;
|
||||
Tag *decoder_tag;
|
||||
|
||||
/** the chunk currently being written to */
|
||||
struct music_chunk *chunk;
|
||||
|
@ -81,8 +82,7 @@ struct decoder {
|
|||
*/
|
||||
unsigned replay_gain_serial;
|
||||
|
||||
decoder(decoder_control *_dc, bool _initial_seek_pending,
|
||||
struct tag *_tag)
|
||||
decoder(decoder_control *_dc, bool _initial_seek_pending, Tag *_tag)
|
||||
:dc(_dc),
|
||||
timestamp(0),
|
||||
initial_seek_pending(_initial_seek_pending),
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
struct config_param;
|
||||
struct input_stream;
|
||||
struct tag;
|
||||
struct Tag;
|
||||
struct tag_handler;
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "Mapper.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
#include "DecoderAPI.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "DecoderList.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
|
@ -381,7 +381,7 @@ decoder_run_song(struct decoder_control *dc,
|
|||
{
|
||||
decoder decoder(dc, dc->start_ms > 0,
|
||||
song->tag != NULL && song->IsFile()
|
||||
? tag_dup(song->tag) : nullptr);
|
||||
? new Tag(*song->tag) : nullptr);
|
||||
int ret;
|
||||
|
||||
dc->state = DECODE_STATE_START;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
#include "DespotifyUtils.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "conf.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
@ -77,14 +77,14 @@ void mpd_despotify_unregister_callback(void (*cb)(struct despotify_session *, in
|
|||
}
|
||||
|
||||
|
||||
struct tag *mpd_despotify_tag_from_track(struct ds_track *track)
|
||||
Tag *
|
||||
mpd_despotify_tag_from_track(struct ds_track *track)
|
||||
{
|
||||
char tracknum[20];
|
||||
char comment[80];
|
||||
char date[20];
|
||||
struct tag *tag;
|
||||
|
||||
tag = tag_new();
|
||||
Tag *tag = new Tag();
|
||||
|
||||
if (!track->has_meta_data)
|
||||
return tag;
|
||||
|
@ -93,12 +93,12 @@ struct tag *mpd_despotify_tag_from_track(struct ds_track *track)
|
|||
g_snprintf(date, sizeof(date), "%d", track->year);
|
||||
g_snprintf(comment, sizeof(comment), "Bitrate %d Kbps, %sgeo restricted",
|
||||
track->file_bitrate / 1000, track->geo_restricted ? "" : "not ");
|
||||
tag_add_item(tag, TAG_TITLE, track->title);
|
||||
tag_add_item(tag, TAG_ARTIST, track->artist->name);
|
||||
tag_add_item(tag, TAG_TRACK, tracknum);
|
||||
tag_add_item(tag, TAG_ALBUM, track->album);
|
||||
tag_add_item(tag, TAG_DATE, date);
|
||||
tag_add_item(tag, TAG_COMMENT, comment);
|
||||
tag->AddItem(TAG_TITLE, track->title);
|
||||
tag->AddItem(TAG_ARTIST, track->artist->name);
|
||||
tag->AddItem(TAG_TRACK, tracknum);
|
||||
tag->AddItem(TAG_ALBUM, track->album);
|
||||
tag->AddItem(TAG_DATE, date);
|
||||
tag->AddItem(TAG_COMMENT, comment);
|
||||
tag->time = track->length / 1000;
|
||||
|
||||
return tag;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#ifndef MPD_DESPOTIFY_H
|
||||
#define MPD_DESPOTIFY_H
|
||||
|
||||
struct Tag;
|
||||
struct despotify_session;
|
||||
struct ds_track;
|
||||
|
||||
|
@ -41,7 +42,8 @@ struct despotify_session *mpd_despotify_get_session(void);
|
|||
*
|
||||
* @return a pointer to the filled in tags structure
|
||||
*/
|
||||
struct tag *mpd_despotify_tag_from_track(struct ds_track *track);
|
||||
Tag *
|
||||
mpd_despotify_tag_from_track(struct ds_track *track);
|
||||
|
||||
/**
|
||||
* Register a despotify callback.
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include "EncoderPlugin.hxx"
|
||||
#include "audio_format.h"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "conf.h"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
struct EncoderPlugin;
|
||||
struct audio_format;
|
||||
struct config_param;
|
||||
struct tag;
|
||||
struct Tag;
|
||||
|
||||
struct Encoder {
|
||||
const EncoderPlugin &plugin;
|
||||
|
@ -66,7 +66,7 @@ struct EncoderPlugin {
|
|||
|
||||
bool (*pre_tag)(Encoder *encoder, GError **error);
|
||||
|
||||
bool (*tag)(Encoder *encoder, const struct tag *tag,
|
||||
bool (*tag)(Encoder *encoder, const Tag *tag,
|
||||
GError **error);
|
||||
|
||||
bool (*write)(Encoder *encoder,
|
||||
|
@ -246,7 +246,7 @@ encoder_pre_tag(Encoder *encoder, GError **error)
|
|||
* @return true on success
|
||||
*/
|
||||
static inline bool
|
||||
encoder_tag(Encoder *encoder, const struct tag *tag, GError **error)
|
||||
encoder_tag(Encoder *encoder, const Tag *tag, GError **error)
|
||||
{
|
||||
assert(encoder->open);
|
||||
assert(!encoder->pre_tag);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "IcyMetaDataParser.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
|
@ -38,8 +38,7 @@ IcyMetaDataParser::Reset()
|
|||
if (data_rest == 0 && meta_size > 0)
|
||||
g_free(meta_data);
|
||||
|
||||
if (tag != nullptr)
|
||||
tag_free(tag);
|
||||
delete tag;
|
||||
|
||||
data_rest = data_size;
|
||||
meta_size = 0;
|
||||
|
@ -66,7 +65,7 @@ IcyMetaDataParser::Data(size_t length)
|
|||
}
|
||||
|
||||
static void
|
||||
icy_add_item(struct tag *tag, enum tag_type type, const char *value)
|
||||
icy_add_item(Tag &tag, enum tag_type type, const char *value)
|
||||
{
|
||||
size_t length = strlen(value);
|
||||
|
||||
|
@ -77,11 +76,11 @@ icy_add_item(struct tag *tag, enum tag_type type, const char *value)
|
|||
}
|
||||
|
||||
if (length > 0)
|
||||
tag_add_item_n(tag, type, value, length);
|
||||
tag.AddItem(type, value, length);
|
||||
}
|
||||
|
||||
static void
|
||||
icy_parse_tag_item(struct tag *tag, const char *item)
|
||||
icy_parse_tag_item(Tag &tag, const char *item)
|
||||
{
|
||||
gchar **p = g_strsplit(item, "=", 0);
|
||||
|
||||
|
@ -95,14 +94,14 @@ icy_parse_tag_item(struct tag *tag, const char *item)
|
|||
g_strfreev(p);
|
||||
}
|
||||
|
||||
static struct tag *
|
||||
static Tag *
|
||||
icy_parse_tag(const char *p)
|
||||
{
|
||||
struct tag *tag = tag_new();
|
||||
Tag *tag = new Tag();
|
||||
gchar **items = g_strsplit(p, ";", 0);
|
||||
|
||||
for (unsigned i = 0; items[i] != nullptr; ++i)
|
||||
icy_parse_tag_item(tag, items[i]);
|
||||
icy_parse_tag_item(*tag, items[i]);
|
||||
|
||||
g_strfreev(items);
|
||||
|
||||
|
@ -157,8 +156,7 @@ IcyMetaDataParser::Meta(const void *data, size_t length)
|
|||
|
||||
/* parse */
|
||||
|
||||
if (tag != nullptr)
|
||||
tag_free(tag);
|
||||
delete tag;
|
||||
|
||||
tag = icy_parse_tag(meta_data);
|
||||
g_free(meta_data);
|
||||
|
|
|
@ -22,13 +22,15 @@
|
|||
|
||||
#include <stddef.h>
|
||||
|
||||
struct Tag;
|
||||
|
||||
class IcyMetaDataParser {
|
||||
size_t data_size, data_rest;
|
||||
|
||||
size_t meta_size, meta_position;
|
||||
char *meta_data;
|
||||
|
||||
struct tag *tag;
|
||||
Tag *tag;
|
||||
|
||||
public:
|
||||
IcyMetaDataParser():data_size(0) {}
|
||||
|
@ -73,8 +75,8 @@ public:
|
|||
*/
|
||||
size_t Meta(const void *data, size_t length);
|
||||
|
||||
struct tag *ReadTag() {
|
||||
struct tag *result = tag;
|
||||
Tag *ReadTag() {
|
||||
Tag *result = tag;
|
||||
tag = nullptr;
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -20,11 +20,12 @@
|
|||
#include "config.h"
|
||||
#include "IcyMetaDataServer.hxx"
|
||||
#include "Page.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
#define G_LOG_DOMAIN "icy_server"
|
||||
|
@ -87,7 +88,7 @@ icy_server_metadata_string(const char *stream_title, const char* stream_url)
|
|||
}
|
||||
|
||||
Page *
|
||||
icy_server_metadata_page(const struct tag *tag, const enum tag_type *types)
|
||||
icy_server_metadata_page(const Tag &tag, const enum tag_type *types)
|
||||
{
|
||||
const gchar *tag_items[TAG_NUM_OF_ITEM_TYPES];
|
||||
gint last_item, item;
|
||||
|
@ -101,7 +102,7 @@ icy_server_metadata_page(const struct tag *tag, const enum tag_type *types)
|
|||
last_item = -1;
|
||||
|
||||
while (*types != TAG_NUM_OF_ITEM_TYPES) {
|
||||
const gchar *tag_item = tag_get_value(tag, *types++);
|
||||
const gchar *tag_item = tag.GetValue(*types++);
|
||||
if (tag_item)
|
||||
tag_items[++last_item] = tag_item;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "TagType.h"
|
||||
|
||||
struct Tag;
|
||||
class Page;
|
||||
|
||||
char*
|
||||
|
@ -30,6 +31,6 @@ icy_server_metadata_header(const char *name,
|
|||
const char *content_type, int metaint);
|
||||
|
||||
Page *
|
||||
icy_server_metadata_page(const struct tag *tag, const enum tag_type *types);
|
||||
icy_server_metadata_page(const Tag &tag, const enum tag_type *types);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -66,7 +66,7 @@ struct input_plugin {
|
|||
*/
|
||||
void (*update)(struct input_stream *is);
|
||||
|
||||
struct tag *(*tag)(struct input_stream *is);
|
||||
Tag *(*tag)(struct input_stream *is);
|
||||
|
||||
/**
|
||||
* Returns true if the next read operation will not block:
|
||||
|
|
|
@ -182,7 +182,7 @@ input_stream_lock_seek(struct input_stream *is, goffset offset, int whence,
|
|||
return input_stream_seek(is, offset, whence, error_r);
|
||||
}
|
||||
|
||||
struct tag *
|
||||
Tag *
|
||||
input_stream_tag(struct input_stream *is)
|
||||
{
|
||||
assert(is != NULL);
|
||||
|
@ -192,7 +192,7 @@ input_stream_tag(struct input_stream *is)
|
|||
: NULL;
|
||||
}
|
||||
|
||||
struct tag *
|
||||
Tag *
|
||||
input_stream_lock_tag(struct input_stream *is)
|
||||
{
|
||||
assert(is != NULL);
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include "Partition.hxx"
|
||||
#include "Volume.hxx"
|
||||
#include "OutputAll.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "conf.h"
|
||||
#include "replay_gain_config.h"
|
||||
#include "Idle.hxx"
|
||||
|
|
|
@ -20,14 +20,13 @@
|
|||
#include "config.h"
|
||||
#include "MusicChunk.hxx"
|
||||
#include "audio_format.h"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
music_chunk::~music_chunk()
|
||||
{
|
||||
if (tag != NULL)
|
||||
tag_free(tag);
|
||||
delete tag;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
|
|
@ -34,6 +34,7 @@ enum {
|
|||
};
|
||||
|
||||
struct audio_format;
|
||||
struct Tag;
|
||||
|
||||
/**
|
||||
* A chunk of music data. Its format is defined by the
|
||||
|
@ -70,7 +71,7 @@ struct music_chunk {
|
|||
* object is owned by this chunk, and must be freed when this
|
||||
* chunk is deinitialized in music_chunk_free()
|
||||
*/
|
||||
struct tag *tag;
|
||||
Tag *tag;
|
||||
|
||||
/**
|
||||
* Replay gain information associated with this chunk.
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "OutputPlugin.hxx"
|
||||
#include "OutputInternal.hxx"
|
||||
#include "audio_format.h"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "conf.h"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <glib.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
#define G_LOG_DOMAIN "output"
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include "output/SolarisOutputPlugin.hxx"
|
||||
#include "output/WinmmOutputPlugin.hxx"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
const struct audio_output_plugin *const audio_output_plugins[] = {
|
||||
#ifdef HAVE_SHOUT
|
||||
&shout_output_plugin,
|
||||
|
|
|
@ -75,7 +75,7 @@ ao_plugin_delay(struct audio_output *ao)
|
|||
}
|
||||
|
||||
void
|
||||
ao_plugin_send_tag(struct audio_output *ao, const struct tag *tag)
|
||||
ao_plugin_send_tag(struct audio_output *ao, const Tag *tag)
|
||||
{
|
||||
if (ao->plugin->send_tag != NULL)
|
||||
ao->plugin->send_tag(ao, tag);
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
struct config_param;
|
||||
struct audio_format;
|
||||
struct tag;
|
||||
struct Tag;
|
||||
|
||||
/**
|
||||
* A plugin which controls an audio output device.
|
||||
|
@ -111,7 +111,7 @@ struct audio_output_plugin {
|
|||
* Display metadata for the next chunk. Optional method,
|
||||
* because not all devices can display metadata.
|
||||
*/
|
||||
void (*send_tag)(struct audio_output *data, const struct tag *tag);
|
||||
void (*send_tag)(struct audio_output *data, const Tag *tag);
|
||||
|
||||
/**
|
||||
* Play a chunk of audio data.
|
||||
|
@ -192,7 +192,7 @@ unsigned
|
|||
ao_plugin_delay(struct audio_output *ao);
|
||||
|
||||
void
|
||||
ao_plugin_send_tag(struct audio_output *ao, const struct tag *tag);
|
||||
ao_plugin_send_tag(struct audio_output *ao, const Tag *tag);
|
||||
|
||||
size_t
|
||||
ao_plugin_play(struct audio_output *ao, const void *chunk, size_t size,
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "CrossFade.hxx"
|
||||
#include "PlayerControl.hxx"
|
||||
#include "OutputAll.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "Idle.hxx"
|
||||
#include "GlobalEvents.hxx"
|
||||
|
||||
|
@ -38,6 +38,8 @@
|
|||
|
||||
#include <glib.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
#define G_LOG_DOMAIN "player_thread"
|
||||
|
||||
|
@ -108,7 +110,7 @@ struct player {
|
|||
* postponed, and sent to the output thread when the new song
|
||||
* really begins.
|
||||
*/
|
||||
struct tag *cross_fade_tag;
|
||||
Tag *cross_fade_tag;
|
||||
|
||||
/**
|
||||
* The current audio format for the audio outputs.
|
||||
|
@ -656,18 +658,17 @@ static void player_process_command(struct player *player)
|
|||
}
|
||||
|
||||
static void
|
||||
update_song_tag(Song *song, const struct tag *new_tag)
|
||||
update_song_tag(Song *song, const Tag &new_tag)
|
||||
{
|
||||
if (song->IsFile())
|
||||
/* don't update tags of local files, only remote
|
||||
streams may change tags dynamically */
|
||||
return;
|
||||
|
||||
struct tag *old_tag = song->tag;
|
||||
song->tag = tag_dup(new_tag);
|
||||
Tag *old_tag = song->tag;
|
||||
song->tag = new Tag(new_tag);
|
||||
|
||||
if (old_tag != NULL)
|
||||
tag_free(old_tag);
|
||||
delete old_tag;
|
||||
|
||||
/* the main thread will update the playlist version when he
|
||||
receives this event */
|
||||
|
@ -694,7 +695,7 @@ play_chunk(struct player_control *pc,
|
|||
assert(chunk->CheckFormat(*format));
|
||||
|
||||
if (chunk->tag != NULL)
|
||||
update_song_tag(song, chunk->tag);
|
||||
update_song_tag(song, *chunk->tag);
|
||||
|
||||
if (chunk->length == 0) {
|
||||
music_buffer_return(player_buffer, chunk);
|
||||
|
@ -760,7 +761,7 @@ play_next_chunk(struct player *player)
|
|||
is being faded in) yet; postpone it until
|
||||
the current song is faded out */
|
||||
player->cross_fade_tag =
|
||||
tag_merge_replace(player->cross_fade_tag,
|
||||
Tag::MergeReplace(player->cross_fade_tag,
|
||||
other_chunk->tag);
|
||||
other_chunk->tag = NULL;
|
||||
|
||||
|
@ -815,7 +816,7 @@ play_next_chunk(struct player *player)
|
|||
/* insert the postponed tag if cross-fading is finished */
|
||||
|
||||
if (player->xfade != XFADE_ENABLED && player->cross_fade_tag != NULL) {
|
||||
chunk->tag = tag_merge_replace(chunk->tag,
|
||||
chunk->tag = Tag::MergeReplace(chunk->tag,
|
||||
player->cross_fade_tag);
|
||||
player->cross_fade_tag = NULL;
|
||||
}
|
||||
|
@ -1080,8 +1081,7 @@ static void do_play(struct player_control *pc, struct decoder_control *dc)
|
|||
music_pipe_clear(player.pipe, player_buffer);
|
||||
music_pipe_free(player.pipe);
|
||||
|
||||
if (player.cross_fade_tag != NULL)
|
||||
tag_free(player.cross_fade_tag);
|
||||
delete player.cross_fade_tag;
|
||||
|
||||
if (player.song != NULL)
|
||||
player.song->Free();
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
struct config_param;
|
||||
struct input_stream;
|
||||
struct tag;
|
||||
struct Tag;
|
||||
struct Song;
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "DatabasePlugin.hxx"
|
||||
#include "DatabaseGlue.hxx"
|
||||
#include "ls.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "Song.hxx"
|
||||
|
@ -39,10 +39,10 @@ merge_song_metadata(Song *dest, const Song *base,
|
|||
{
|
||||
dest->tag = base->tag != NULL
|
||||
? (add->tag != NULL
|
||||
? tag_merge(base->tag, add->tag)
|
||||
: tag_dup(base->tag))
|
||||
? Tag::Merge(*base->tag, *add->tag)
|
||||
: new Tag(*base->tag))
|
||||
: (add->tag != NULL
|
||||
? tag_dup(add->tag)
|
||||
? new Tag(*add->tag)
|
||||
: NULL);
|
||||
|
||||
dest->mtime = base->mtime;
|
||||
|
|
|
@ -20,11 +20,12 @@
|
|||
#include "config.h"
|
||||
#include "Song.hxx"
|
||||
#include "Directory.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
Directory detached_root;
|
||||
|
||||
|
@ -94,7 +95,7 @@ Song::DupDetached() const
|
|||
} else
|
||||
song = song_alloc(uri, nullptr);
|
||||
|
||||
song->tag = tag_dup(tag);
|
||||
song->tag = tag != nullptr ? new Tag(*tag) : nullptr;
|
||||
song->mtime = mtime;
|
||||
song->start_ms = start_ms;
|
||||
song->end_ms = end_ms;
|
||||
|
@ -105,8 +106,7 @@ Song::DupDetached() const
|
|||
void
|
||||
Song::Free()
|
||||
{
|
||||
if (tag != nullptr)
|
||||
tag_free(tag);
|
||||
delete tag;
|
||||
g_free(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#define SONG_FILE "file: "
|
||||
#define SONG_TIME "Time: "
|
||||
|
||||
struct Tag;
|
||||
|
||||
/**
|
||||
* A dummy #directory instance that is used for "detached" song
|
||||
* copies.
|
||||
|
@ -46,7 +48,7 @@ struct Song {
|
|||
*/
|
||||
struct list_head siblings;
|
||||
|
||||
struct tag *tag;
|
||||
Tag *tag;
|
||||
Directory *parent;
|
||||
time_t mtime;
|
||||
|
||||
|
|
|
@ -20,11 +20,12 @@
|
|||
#include "config.h"
|
||||
#include "SongFilter.hxx"
|
||||
#include "Song.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define LOCATE_TAG_FILE_KEY "file"
|
||||
|
@ -74,14 +75,14 @@ SongFilter::Item::StringMatch(const char *s) const
|
|||
}
|
||||
|
||||
bool
|
||||
SongFilter::Item::Match(const tag_item &item) const
|
||||
SongFilter::Item::Match(const TagItem &item) const
|
||||
{
|
||||
return (tag == LOCATE_TAG_ANY_TYPE || (unsigned)item.type == tag) &&
|
||||
StringMatch(item.value);
|
||||
}
|
||||
|
||||
bool
|
||||
SongFilter::Item::Match(const struct tag &_tag) const
|
||||
SongFilter::Item::Match(const Tag &_tag) const
|
||||
{
|
||||
bool visited_types[TAG_NUM_OF_ITEM_TYPES];
|
||||
std::fill(visited_types, visited_types + TAG_NUM_OF_ITEM_TYPES, false);
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
#define LOCATE_TAG_FILE_TYPE TAG_NUM_OF_ITEM_TYPES+10
|
||||
#define LOCATE_TAG_ANY_TYPE TAG_NUM_OF_ITEM_TYPES+20
|
||||
|
||||
struct tag;
|
||||
struct tag_item;
|
||||
struct Tag;
|
||||
struct TagItem;
|
||||
struct Song;
|
||||
|
||||
class SongFilter {
|
||||
|
@ -65,10 +65,10 @@ class SongFilter {
|
|||
bool StringMatch(const char *s) const;
|
||||
|
||||
gcc_pure
|
||||
bool Match(const tag_item &tag_item) const;
|
||||
bool Match(const TagItem &tag_item) const;
|
||||
|
||||
gcc_pure
|
||||
bool Match(const struct tag &tag) const;
|
||||
bool Match(const Tag &tag) const;
|
||||
|
||||
gcc_pure
|
||||
bool Match(const Song &song) const;
|
||||
|
@ -91,7 +91,7 @@ public:
|
|||
bool Parse(unsigned argc, char *argv[], bool fold_case=false);
|
||||
|
||||
gcc_pure
|
||||
bool Match(const tag &tag) const;
|
||||
bool Match(const Tag &tag) const;
|
||||
|
||||
gcc_pure
|
||||
bool Match(const Song &song) const;
|
||||
|
|
|
@ -69,6 +69,6 @@ song_print_info(Client *client, Song *song)
|
|||
if (song->mtime > 0)
|
||||
time_print(client, "Last-Modified", song->mtime);
|
||||
|
||||
if (song->tag)
|
||||
tag_print(client, song->tag);
|
||||
if (song->tag != nullptr)
|
||||
tag_print(client, *song->tag);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "TagSave.hxx"
|
||||
#include "Directory.hxx"
|
||||
#include "TextFile.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "util/StringUtil.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
@ -52,8 +52,8 @@ song_save(FILE *fp, const Song *song)
|
|||
else if (song->start_ms > 0)
|
||||
fprintf(fp, "Range: %u-\n", song->start_ms);
|
||||
|
||||
if (song->tag != NULL)
|
||||
tag_save(fp, song->tag);
|
||||
if (song->tag != nullptr)
|
||||
tag_save(fp, *song->tag);
|
||||
|
||||
fprintf(fp, SONG_MTIME ": %li\n", (long)song->mtime);
|
||||
fprintf(fp, SONG_END "\n");
|
||||
|
@ -75,7 +75,7 @@ song_load(TextFile &file, Directory *parent, const char *uri,
|
|||
colon = strchr(line, ':');
|
||||
if (colon == NULL || colon == line) {
|
||||
if (song->tag != NULL)
|
||||
tag_end_add(song->tag);
|
||||
song->tag->EndAdd();
|
||||
song->Free();
|
||||
|
||||
g_set_error(error_r, song_save_quark(), 0,
|
||||
|
@ -88,22 +88,22 @@ song_load(TextFile &file, Directory *parent, const char *uri,
|
|||
|
||||
if ((type = tag_name_parse(line)) != TAG_NUM_OF_ITEM_TYPES) {
|
||||
if (!song->tag) {
|
||||
song->tag = tag_new();
|
||||
tag_begin_add(song->tag);
|
||||
song->tag = new Tag();
|
||||
song->tag->BeginAdd();
|
||||
}
|
||||
|
||||
tag_add_item(song->tag, type, value);
|
||||
song->tag->AddItem(type, value);
|
||||
} else if (strcmp(line, "Time") == 0) {
|
||||
if (!song->tag) {
|
||||
song->tag = tag_new();
|
||||
tag_begin_add(song->tag);
|
||||
song->tag = new Tag();
|
||||
song->tag->BeginAdd();
|
||||
}
|
||||
|
||||
song->tag->time = atoi(value);
|
||||
} else if (strcmp(line, "Playlist") == 0) {
|
||||
if (!song->tag) {
|
||||
song->tag = tag_new();
|
||||
tag_begin_add(song->tag);
|
||||
song->tag = new Tag();
|
||||
song->tag->BeginAdd();
|
||||
}
|
||||
|
||||
song->tag->has_playlist = strcmp(value, "yes") == 0;
|
||||
|
@ -117,7 +117,7 @@ song_load(TextFile &file, Directory *parent, const char *uri,
|
|||
song->end_ms = strtoul(endptr + 1, NULL, 10);
|
||||
} else {
|
||||
if (song->tag != NULL)
|
||||
tag_end_add(song->tag);
|
||||
song->tag->EndAdd();
|
||||
song->Free();
|
||||
|
||||
g_set_error(error_r, song_save_quark(), 0,
|
||||
|
@ -127,7 +127,7 @@ song_load(TextFile &file, Directory *parent, const char *uri,
|
|||
}
|
||||
|
||||
if (song->tag != NULL)
|
||||
tag_end_add(song->tag);
|
||||
song->tag->EndAdd();
|
||||
|
||||
return song;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "SongSort.hxx"
|
||||
#include "Song.hxx"
|
||||
#include "util/list.h"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
extern "C" {
|
||||
#include "util/list_sort.h"
|
||||
|
@ -33,10 +33,10 @@ extern "C" {
|
|||
#include <stdlib.h>
|
||||
|
||||
static const char *
|
||||
tag_get_value_checked(const struct tag *tag, enum tag_type type)
|
||||
tag_get_value_checked(const Tag *tag, enum tag_type type)
|
||||
{
|
||||
return tag != NULL
|
||||
? tag_get_value(tag, type)
|
||||
? tag->GetValue(type)
|
||||
: NULL;
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ compare_utf8_string(const char *a, const char *b)
|
|||
* NULL.
|
||||
*/
|
||||
static int
|
||||
compare_string_tag_item(const struct tag *a, const struct tag *b,
|
||||
compare_string_tag_item(const Tag *a, const Tag *b,
|
||||
enum tag_type type)
|
||||
{
|
||||
return compare_utf8_string(tag_get_value_checked(a, type),
|
||||
|
@ -84,7 +84,7 @@ compare_number_string(const char *a, const char *b)
|
|||
}
|
||||
|
||||
static int
|
||||
compare_tag_item(const struct tag *a, const struct tag *b, enum tag_type type)
|
||||
compare_tag_item(const Tag *a, const Tag *b, enum tag_type type)
|
||||
{
|
||||
return compare_number_string(tag_get_value_checked(a, type),
|
||||
tag_get_value_checked(b, type));
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "Mapper.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
#include "fs/FileSystem.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "input_stream.h"
|
||||
#include "DecoderPlugin.hxx"
|
||||
#include "DecoderList.hxx"
|
||||
|
@ -100,10 +100,8 @@ Song::UpdateFile()
|
|||
if (path_fs.IsNull())
|
||||
return false;
|
||||
|
||||
if (tag != NULL) {
|
||||
tag_free(tag);
|
||||
tag = NULL;
|
||||
}
|
||||
delete tag;
|
||||
tag = nullptr;
|
||||
|
||||
if (!StatFile(path_fs, st) || !S_ISREG(st.st_mode)) {
|
||||
return false;
|
||||
|
@ -116,12 +114,12 @@ Song::UpdateFile()
|
|||
|
||||
do {
|
||||
/* load file tag */
|
||||
tag = tag_new();
|
||||
tag = new Tag();
|
||||
if (decoder_plugin_scan_file(plugin, path_fs.c_str(),
|
||||
&full_tag_handler, tag))
|
||||
break;
|
||||
|
||||
tag_free(tag);
|
||||
delete tag;
|
||||
tag = nullptr;
|
||||
|
||||
/* fall back to stream tag */
|
||||
|
@ -136,13 +134,13 @@ Song::UpdateFile()
|
|||
|
||||
/* now try the stream_tag() method */
|
||||
if (is != NULL) {
|
||||
tag = tag_new();
|
||||
tag = new Tag();
|
||||
if (decoder_plugin_scan_stream(plugin, is,
|
||||
&full_tag_handler,
|
||||
tag))
|
||||
break;
|
||||
|
||||
tag_free(tag);
|
||||
delete tag;
|
||||
tag = nullptr;
|
||||
|
||||
input_stream_lock_seek(is, 0, SEEK_SET, NULL);
|
||||
|
@ -155,7 +153,7 @@ Song::UpdateFile()
|
|||
if (is != NULL)
|
||||
input_stream_close(is);
|
||||
|
||||
if (tag != nullptr && tag_is_empty(tag))
|
||||
if (tag != nullptr && tag->IsEmpty())
|
||||
tag_scan_fallback(path_fs.c_str(), &full_tag_handler, tag);
|
||||
|
||||
return tag != nullptr;
|
||||
|
@ -179,13 +177,12 @@ Song::UpdateFileInArchive()
|
|||
if (plugin == NULL)
|
||||
return false;
|
||||
|
||||
if (tag != nullptr)
|
||||
tag_free(tag);
|
||||
delete tag;
|
||||
|
||||
//accept every file that has music suffix
|
||||
//because we don't support tag reading through
|
||||
//input streams
|
||||
tag = tag_new();
|
||||
tag = new Tag();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
245
src/Tag.cxx
245
src/Tag.cxx
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "TagInternal.hxx"
|
||||
#include "TagPool.hxx"
|
||||
#include "conf.h"
|
||||
|
@ -29,6 +29,7 @@
|
|||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Maximum number of items managed in the bulk list; if it is
|
||||
|
@ -40,7 +41,7 @@ static struct {
|
|||
#ifndef NDEBUG
|
||||
bool busy;
|
||||
#endif
|
||||
struct tag_item *items[BULK_MAX];
|
||||
TagItem *items[BULK_MAX];
|
||||
} bulk;
|
||||
|
||||
bool ignore_tag_items[TAG_NUM_OF_ITEM_TYPES];
|
||||
|
@ -75,9 +76,10 @@ tag_name_parse_i(const char *name)
|
|||
return TAG_NUM_OF_ITEM_TYPES;
|
||||
}
|
||||
|
||||
static size_t items_size(const struct tag *tag)
|
||||
static size_t
|
||||
items_size(const Tag &tag)
|
||||
{
|
||||
return tag->num_items * sizeof(struct tag_item *);
|
||||
return tag.num_items * sizeof(TagItem *);
|
||||
}
|
||||
|
||||
void tag_lib_init(void)
|
||||
|
@ -130,127 +132,101 @@ void tag_lib_init(void)
|
|||
g_free(temp);
|
||||
}
|
||||
|
||||
struct tag *tag_new(void)
|
||||
void
|
||||
Tag::DeleteItem(unsigned idx)
|
||||
{
|
||||
struct tag *ret = g_new(struct tag, 1);
|
||||
ret->items = nullptr;
|
||||
ret->time = -1;
|
||||
ret->has_playlist = false;
|
||||
ret->num_items = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void tag_delete_item(struct tag *tag, unsigned idx)
|
||||
{
|
||||
assert(idx < tag->num_items);
|
||||
tag->num_items--;
|
||||
assert(idx < num_items);
|
||||
--num_items;
|
||||
|
||||
tag_pool_lock.lock();
|
||||
tag_pool_put_item(tag->items[idx]);
|
||||
tag_pool_put_item(items[idx]);
|
||||
tag_pool_lock.unlock();
|
||||
|
||||
if (tag->num_items - idx > 0) {
|
||||
memmove(tag->items + idx, tag->items + idx + 1,
|
||||
(tag->num_items - idx) * sizeof(tag->items[0]));
|
||||
if (num_items - idx > 0) {
|
||||
memmove(items + idx, items + idx + 1,
|
||||
(num_items - idx) * sizeof(items[0]));
|
||||
}
|
||||
|
||||
if (tag->num_items > 0) {
|
||||
tag->items = (struct tag_item **)
|
||||
g_realloc(tag->items, items_size(tag));
|
||||
if (num_items > 0) {
|
||||
items = (TagItem **)
|
||||
g_realloc(items, items_size(*this));
|
||||
} else {
|
||||
g_free(tag->items);
|
||||
tag->items = nullptr;
|
||||
g_free(items);
|
||||
items = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void tag_clear_items_by_type(struct tag *tag, enum tag_type type)
|
||||
void
|
||||
Tag::ClearItemsByType(tag_type type)
|
||||
{
|
||||
for (unsigned i = 0; i < tag->num_items; i++) {
|
||||
if (tag->items[i]->type == type) {
|
||||
tag_delete_item(tag, i);
|
||||
for (unsigned i = 0; i < num_items; i++) {
|
||||
if (items[i]->type == type) {
|
||||
DeleteItem(i);
|
||||
/* decrement since when just deleted this node */
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tag_free(struct tag *tag)
|
||||
Tag::~Tag()
|
||||
{
|
||||
int i;
|
||||
|
||||
assert(tag != nullptr);
|
||||
|
||||
tag_pool_lock.lock();
|
||||
for (i = tag->num_items; --i >= 0; )
|
||||
tag_pool_put_item(tag->items[i]);
|
||||
for (int i = num_items; --i >= 0; )
|
||||
tag_pool_put_item(items[i]);
|
||||
tag_pool_lock.unlock();
|
||||
|
||||
if (tag->items == bulk.items) {
|
||||
if (items == bulk.items) {
|
||||
#ifndef NDEBUG
|
||||
assert(bulk.busy);
|
||||
bulk.busy = false;
|
||||
#endif
|
||||
} else
|
||||
g_free(tag->items);
|
||||
|
||||
g_free(tag);
|
||||
g_free(items);
|
||||
}
|
||||
|
||||
struct tag *tag_dup(const struct tag *tag)
|
||||
Tag::Tag(const Tag &other)
|
||||
:time(other.time), has_playlist(other.has_playlist),
|
||||
items(nullptr),
|
||||
num_items(other.num_items)
|
||||
{
|
||||
struct tag *ret;
|
||||
if (num_items > 0) {
|
||||
items = (TagItem **)g_malloc(items_size(other));
|
||||
|
||||
if (!tag)
|
||||
return nullptr;
|
||||
|
||||
ret = tag_new();
|
||||
ret->time = tag->time;
|
||||
ret->has_playlist = tag->has_playlist;
|
||||
ret->num_items = tag->num_items;
|
||||
ret->items = ret->num_items > 0
|
||||
? (struct tag_item **)g_malloc(items_size(tag))
|
||||
: nullptr;
|
||||
|
||||
tag_pool_lock.lock();
|
||||
for (unsigned i = 0; i < tag->num_items; i++)
|
||||
ret->items[i] = tag_pool_dup_item(tag->items[i]);
|
||||
tag_pool_lock.unlock();
|
||||
|
||||
return ret;
|
||||
tag_pool_lock.lock();
|
||||
for (unsigned i = 0; i < num_items; i++)
|
||||
items[i] = tag_pool_dup_item(other.items[i]);
|
||||
tag_pool_lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
struct tag *
|
||||
tag_merge(const struct tag *base, const struct tag *add)
|
||||
Tag *
|
||||
Tag::Merge(const Tag &base, const Tag &add)
|
||||
{
|
||||
struct tag *ret;
|
||||
unsigned n;
|
||||
|
||||
assert(base != nullptr);
|
||||
assert(add != nullptr);
|
||||
|
||||
/* allocate new tag object */
|
||||
|
||||
ret = tag_new();
|
||||
ret->time = add->time > 0 ? add->time : base->time;
|
||||
ret->num_items = base->num_items + add->num_items;
|
||||
Tag *ret = new Tag();
|
||||
ret->time = add.time > 0 ? add.time : base.time;
|
||||
ret->num_items = base.num_items + add.num_items;
|
||||
ret->items = ret->num_items > 0
|
||||
? (struct tag_item **)g_malloc(items_size(ret))
|
||||
? (TagItem **)g_malloc(items_size(*ret))
|
||||
: nullptr;
|
||||
|
||||
tag_pool_lock.lock();
|
||||
|
||||
/* copy all items from "add" */
|
||||
|
||||
for (unsigned i = 0; i < add->num_items; ++i)
|
||||
ret->items[i] = tag_pool_dup_item(add->items[i]);
|
||||
for (unsigned i = 0; i < add.num_items; ++i)
|
||||
ret->items[i] = tag_pool_dup_item(add.items[i]);
|
||||
|
||||
n = add->num_items;
|
||||
n = add.num_items;
|
||||
|
||||
/* copy additional items from "base" */
|
||||
|
||||
for (unsigned i = 0; i < base->num_items; ++i)
|
||||
if (!tag_has_type(add, base->items[i]->type))
|
||||
ret->items[n++] = tag_pool_dup_item(base->items[i]);
|
||||
for (unsigned i = 0; i < base.num_items; ++i)
|
||||
if (!add.HasType(base.items[i]->type))
|
||||
ret->items[n++] = tag_pool_dup_item(base.items[i]);
|
||||
|
||||
tag_pool_lock.unlock();
|
||||
|
||||
|
@ -261,15 +237,15 @@ tag_merge(const struct tag *base, const struct tag *add)
|
|||
assert(n > 0);
|
||||
|
||||
ret->num_items = n;
|
||||
ret->items = (struct tag_item **)
|
||||
g_realloc(ret->items, items_size(ret));
|
||||
ret->items = (TagItem **)
|
||||
g_realloc(ret->items, items_size(*ret));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct tag *
|
||||
tag_merge_replace(struct tag *base, struct tag *add)
|
||||
Tag *
|
||||
Tag::MergeReplace(Tag *base, Tag *add)
|
||||
{
|
||||
if (add == nullptr)
|
||||
return base;
|
||||
|
@ -277,48 +253,44 @@ tag_merge_replace(struct tag *base, struct tag *add)
|
|||
if (base == nullptr)
|
||||
return add;
|
||||
|
||||
struct tag *tag = tag_merge(base, add);
|
||||
tag_free(base);
|
||||
tag_free(add);
|
||||
Tag *tag = Merge(*base, *add);
|
||||
delete base;
|
||||
delete add;
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
const char *
|
||||
tag_get_value(const struct tag *tag, enum tag_type type)
|
||||
Tag::GetValue(tag_type type) const
|
||||
{
|
||||
assert(tag != nullptr);
|
||||
assert(type < TAG_NUM_OF_ITEM_TYPES);
|
||||
|
||||
for (unsigned i = 0; i < tag->num_items; i++)
|
||||
if (tag->items[i]->type == type)
|
||||
return tag->items[i]->value;
|
||||
for (unsigned i = 0; i < num_items; i++)
|
||||
if (items[i]->type == type)
|
||||
return items[i]->value;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool tag_has_type(const struct tag *tag, enum tag_type type)
|
||||
bool
|
||||
Tag::HasType(tag_type type) const
|
||||
{
|
||||
return tag_get_value(tag, type) != nullptr;
|
||||
return GetValue(type) != nullptr;
|
||||
}
|
||||
|
||||
bool tag_equal(const struct tag *tag1, const struct tag *tag2)
|
||||
bool
|
||||
Tag::Equals(const Tag &other) const
|
||||
{
|
||||
if (tag1 == nullptr && tag2 == nullptr)
|
||||
return true;
|
||||
else if (!tag1 || !tag2)
|
||||
if (time != other.time)
|
||||
return false;
|
||||
|
||||
if (tag1->time != tag2->time)
|
||||
if (num_items != other.num_items)
|
||||
return false;
|
||||
|
||||
if (tag1->num_items != tag2->num_items)
|
||||
return false;
|
||||
|
||||
for (unsigned i = 0; i < tag1->num_items; i++) {
|
||||
if (tag1->items[i]->type != tag2->items[i]->type)
|
||||
for (unsigned i = 0; i < num_items; i++) {
|
||||
if (items[i]->type != other.items[i]->type)
|
||||
return false;
|
||||
if (strcmp(tag1->items[i]->value, tag2->items[i]->value)) {
|
||||
if (strcmp(items[i]->value, other.items[i]->value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -368,32 +340,33 @@ fix_utf8(const char *str, size_t length)
|
|||
return patch_utf8(str, length, end);
|
||||
}
|
||||
|
||||
void tag_begin_add(struct tag *tag)
|
||||
void
|
||||
Tag::BeginAdd()
|
||||
{
|
||||
assert(!bulk.busy);
|
||||
assert(tag != nullptr);
|
||||
assert(tag->items == nullptr);
|
||||
assert(tag->num_items == 0);
|
||||
assert(items == nullptr);
|
||||
assert(num_items == 0);
|
||||
|
||||
#ifndef NDEBUG
|
||||
bulk.busy = true;
|
||||
#endif
|
||||
tag->items = bulk.items;
|
||||
items = bulk.items;
|
||||
}
|
||||
|
||||
void tag_end_add(struct tag *tag)
|
||||
void
|
||||
Tag::EndAdd()
|
||||
{
|
||||
if (tag->items == bulk.items) {
|
||||
assert(tag->num_items <= BULK_MAX);
|
||||
if (items == bulk.items) {
|
||||
assert(num_items <= BULK_MAX);
|
||||
|
||||
if (tag->num_items > 0) {
|
||||
if (num_items > 0) {
|
||||
/* copy the tag items from the bulk list over
|
||||
to a new list (which fits exactly) */
|
||||
tag->items = (struct tag_item **)
|
||||
g_malloc(items_size(tag));
|
||||
memcpy(tag->items, bulk.items, items_size(tag));
|
||||
items = (TagItem **)
|
||||
g_malloc(items_size(*this));
|
||||
memcpy(items, bulk.items, items_size(*this));
|
||||
} else
|
||||
tag->items = nullptr;
|
||||
items = nullptr;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@ -459,11 +432,10 @@ fix_tag_value(const char *p, size_t length)
|
|||
return cleared;
|
||||
}
|
||||
|
||||
static void
|
||||
tag_add_item_internal(struct tag *tag, enum tag_type type,
|
||||
const char *value, size_t len)
|
||||
void
|
||||
Tag::AddItemInternal(tag_type type, const char *value, size_t len)
|
||||
{
|
||||
unsigned int i = tag->num_items;
|
||||
unsigned int i = num_items;
|
||||
char *p;
|
||||
|
||||
p = fix_tag_value(value, len);
|
||||
|
@ -472,37 +444,42 @@ tag_add_item_internal(struct tag *tag, enum tag_type type,
|
|||
len = strlen(value);
|
||||
}
|
||||
|
||||
tag->num_items++;
|
||||
num_items++;
|
||||
|
||||
if (tag->items != bulk.items)
|
||||
if (items != bulk.items)
|
||||
/* bulk mode disabled */
|
||||
tag->items = (struct tag_item **)
|
||||
g_realloc(tag->items, items_size(tag));
|
||||
else if (tag->num_items >= BULK_MAX) {
|
||||
items = (TagItem **)
|
||||
g_realloc(items, items_size(*this));
|
||||
else if (num_items >= BULK_MAX) {
|
||||
/* bulk list already full - switch back to non-bulk */
|
||||
assert(bulk.busy);
|
||||
|
||||
tag->items = (struct tag_item **)g_malloc(items_size(tag));
|
||||
memcpy(tag->items, bulk.items,
|
||||
items_size(tag) - sizeof(struct tag_item *));
|
||||
items = (TagItem **)g_malloc(items_size(*this));
|
||||
memcpy(items, bulk.items,
|
||||
items_size(*this) - sizeof(TagItem *));
|
||||
}
|
||||
|
||||
tag_pool_lock.lock();
|
||||
tag->items[i] = tag_pool_get_item(type, value, len);
|
||||
items[i] = tag_pool_get_item(type, value, len);
|
||||
tag_pool_lock.unlock();
|
||||
|
||||
g_free(p);
|
||||
}
|
||||
|
||||
void tag_add_item_n(struct tag *tag, enum tag_type type,
|
||||
const char *value, size_t len)
|
||||
void
|
||||
Tag::AddItem(tag_type type, const char *value, size_t len)
|
||||
{
|
||||
if (ignore_tag_items[type])
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!value || !len)
|
||||
return;
|
||||
|
||||
tag_add_item_internal(tag, type, value, len);
|
||||
if (value == nullptr || len == 0)
|
||||
return;
|
||||
|
||||
AddItemInternal(type, value, len);
|
||||
}
|
||||
|
||||
void
|
||||
Tag::AddItem(tag_type type, const char *value)
|
||||
{
|
||||
AddItem(type, value, strlen(value));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* Copyright (C) 2003-2013 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPD_TAG_HXX
|
||||
#define MPD_TAG_HXX
|
||||
|
||||
#include "TagType.h"
|
||||
#include "gcc.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* One tag value. It is a mapping of #tag_type to am arbitrary string
|
||||
* value. Each tag can have multiple items of one tag type (although
|
||||
* few clients support that).
|
||||
*/
|
||||
struct TagItem {
|
||||
/** the type of this item */
|
||||
enum tag_type type;
|
||||
|
||||
/**
|
||||
* the value of this tag; this is a variable length string
|
||||
*/
|
||||
char value[sizeof(long)];
|
||||
} gcc_packed;
|
||||
|
||||
/**
|
||||
* The meta information about a song file. It is a MPD specific
|
||||
* subset of tags (e.g. from ID3, vorbis comments, ...).
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
int time;
|
||||
|
||||
/**
|
||||
* Does this file have an embedded playlist (e.g. embedded CUE
|
||||
* sheet)?
|
||||
*/
|
||||
bool has_playlist;
|
||||
|
||||
/** 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(const Tag &other);
|
||||
|
||||
Tag(Tag &&other)
|
||||
:time(other.time), has_playlist(other.has_playlist),
|
||||
items(other.items), num_items(other.num_items) {
|
||||
other.items = nullptr;
|
||||
other.num_items = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free the tag object and all its items.
|
||||
*/
|
||||
~Tag();
|
||||
|
||||
Tag &operator=(const Tag &other) = delete;
|
||||
|
||||
Tag &operator=(Tag &&other) {
|
||||
time = other.time;
|
||||
has_playlist = other.has_playlist;
|
||||
std::swap(items, other.items);
|
||||
std::swap(num_items, other.num_items);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the tag contains no items. This ignores the "time"
|
||||
* attribute.
|
||||
*/
|
||||
bool IsEmpty() const {
|
||||
return num_items == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the tag contains any information.
|
||||
*/
|
||||
bool IsDefined() const {
|
||||
return !IsEmpty() || time >= 0;
|
||||
}
|
||||
|
||||
void DeleteItem(unsigned i);
|
||||
|
||||
/**
|
||||
* Clear all tag items with the specified type.
|
||||
*/
|
||||
void ClearItemsByType(tag_type type);
|
||||
|
||||
/**
|
||||
* Gives an optional hint to the tag library that we will now
|
||||
* add several tag items; this is used by the library to
|
||||
* optimize memory allocation. Only one tag may be in this
|
||||
* state, and this tag must not have any items yet. You must
|
||||
* call tag_end_add() when you are done.
|
||||
*/
|
||||
void BeginAdd();
|
||||
|
||||
/**
|
||||
* Finishes the operation started with tag_begin_add().
|
||||
*/
|
||||
void EndAdd();
|
||||
|
||||
/**
|
||||
* 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(tag_type 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(tag_type type, const char *value);
|
||||
|
||||
/**
|
||||
* Merges the data from two tags. If both tags share data for the
|
||||
* same tag_type, only data from "add" is used.
|
||||
*
|
||||
* @return a newly allocated tag
|
||||
*/
|
||||
gcc_malloc
|
||||
static Tag *Merge(const Tag &base, const Tag &add);
|
||||
|
||||
/**
|
||||
* Merges the data from two tags. Any of the two may be NULL. Both
|
||||
* are freed by this function.
|
||||
*
|
||||
* @return a newly allocated tag
|
||||
*/
|
||||
gcc_malloc
|
||||
static Tag *MergeReplace(Tag *base, Tag *add);
|
||||
|
||||
/**
|
||||
* Returns the first value of the specified tag type, or NULL if none
|
||||
* is present in this tag object.
|
||||
*/
|
||||
gcc_pure
|
||||
const char *GetValue(tag_type type) const;
|
||||
|
||||
/**
|
||||
* Checks whether the tag contains one or more items with
|
||||
* the specified type.
|
||||
*/
|
||||
bool HasType(tag_type type) const;
|
||||
|
||||
/**
|
||||
* Compares two tags, including the duration and all tag items. The
|
||||
* order of the tag items matters.
|
||||
*/
|
||||
gcc_pure
|
||||
bool Equals(const Tag &other) const;
|
||||
|
||||
private:
|
||||
void AddItemInternal(tag_type type, const char *value, size_t len);
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the string, and convert it into a #tag_type. Returns
|
||||
* #TAG_NUM_OF_ITEM_TYPES if the string could not be recognized.
|
||||
*/
|
||||
enum tag_type
|
||||
tag_name_parse(const char *name);
|
||||
|
||||
/**
|
||||
* Parse the string, and convert it into a #tag_type. Returns
|
||||
* #TAG_NUM_OF_ITEM_TYPES if the string could not be recognized.
|
||||
*
|
||||
* Case does not matter.
|
||||
*/
|
||||
enum tag_type
|
||||
tag_name_parse_i(const char *name);
|
||||
|
||||
/**
|
||||
* Initializes the tag library.
|
||||
*/
|
||||
void
|
||||
tag_lib_init();
|
||||
|
||||
#endif
|
|
@ -19,14 +19,14 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "TagHandler.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
static void
|
||||
add_tag_duration(unsigned seconds, void *ctx)
|
||||
{
|
||||
struct tag *tag = (struct tag *)ctx;
|
||||
Tag *tag = (Tag *)ctx;
|
||||
|
||||
tag->time = seconds;
|
||||
}
|
||||
|
@ -34,9 +34,9 @@ add_tag_duration(unsigned seconds, void *ctx)
|
|||
static void
|
||||
add_tag_tag(enum tag_type type, const char *value, void *ctx)
|
||||
{
|
||||
struct tag *tag = (struct tag *)ctx;
|
||||
Tag *tag = (Tag *)ctx;
|
||||
|
||||
tag_add_item(tag, type, value);
|
||||
tag->AddItem(type, value);
|
||||
}
|
||||
|
||||
const struct tag_handler add_tag_handler = {
|
||||
|
@ -48,7 +48,7 @@ const struct tag_handler add_tag_handler = {
|
|||
static void
|
||||
full_tag_pair(const char *name, G_GNUC_UNUSED const char *value, void *ctx)
|
||||
{
|
||||
struct tag *tag = (struct tag *)ctx;
|
||||
Tag *tag = (Tag *)ctx;
|
||||
|
||||
if (g_ascii_strcasecmp(name, "cuesheet") == 0)
|
||||
tag->has_playlist = true;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "TagId3.hxx"
|
||||
#include "TagHandler.hxx"
|
||||
#include "TagTable.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
extern "C" {
|
||||
#include "riff.h"
|
||||
|
@ -385,14 +385,15 @@ scan_id3_tag(struct id3_tag *tag,
|
|||
tag_id3_import_ufid(tag, handler, handler_ctx);
|
||||
}
|
||||
|
||||
struct tag *tag_id3_import(struct id3_tag * tag)
|
||||
Tag *
|
||||
tag_id3_import(struct id3_tag *tag)
|
||||
{
|
||||
struct tag *ret = tag_new();
|
||||
Tag *ret = new Tag();
|
||||
|
||||
scan_id3_tag(tag, &add_tag_handler, ret);
|
||||
|
||||
if (tag_is_empty(ret)) {
|
||||
tag_free(ret);
|
||||
if (ret->IsEmpty()) {
|
||||
delete ret;
|
||||
ret = nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
#include "gerror.h"
|
||||
|
||||
struct tag_handler;
|
||||
struct tag;
|
||||
struct Tag;
|
||||
struct id3_tag;
|
||||
|
||||
#ifdef HAVE_ID3TAG
|
||||
|
||||
|
@ -33,8 +34,8 @@ bool
|
|||
tag_id3_scan(const char *path_fs,
|
||||
const struct tag_handler *handler, void *handler_ctx);
|
||||
|
||||
struct id3_tag;
|
||||
struct tag *tag_id3_import(struct id3_tag *);
|
||||
Tag *
|
||||
tag_id3_import(struct id3_tag *);
|
||||
|
||||
/**
|
||||
* Loads the ID3 tags from the file into a libid3tag object. The
|
||||
|
|
|
@ -19,11 +19,12 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "TagPool.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
Mutex tag_pool_lock;
|
||||
|
||||
|
@ -32,7 +33,7 @@ Mutex tag_pool_lock;
|
|||
struct slot {
|
||||
struct slot *next;
|
||||
unsigned char ref;
|
||||
struct tag_item item;
|
||||
TagItem item;
|
||||
} mpd_packed;
|
||||
|
||||
static struct slot *slots[NUM_SLOTS];
|
||||
|
@ -64,7 +65,7 @@ calc_hash(enum tag_type type, const char *p)
|
|||
}
|
||||
|
||||
static inline struct slot *
|
||||
tag_item_to_slot(struct tag_item *item)
|
||||
tag_item_to_slot(TagItem *item)
|
||||
{
|
||||
return (struct slot*)(((char*)item) - offsetof(struct slot, item));
|
||||
}
|
||||
|
@ -85,7 +86,7 @@ static struct slot *slot_alloc(struct slot *next,
|
|||
return slot;
|
||||
}
|
||||
|
||||
struct tag_item *
|
||||
TagItem *
|
||||
tag_pool_get_item(enum tag_type type, const char *value, size_t length)
|
||||
{
|
||||
struct slot **slot_p, *slot;
|
||||
|
@ -107,7 +108,8 @@ tag_pool_get_item(enum tag_type type, const char *value, size_t length)
|
|||
return &slot->item;
|
||||
}
|
||||
|
||||
struct tag_item *tag_pool_dup_item(struct tag_item *item)
|
||||
TagItem *
|
||||
tag_pool_dup_item(TagItem *item)
|
||||
{
|
||||
struct slot *slot = tag_item_to_slot(item);
|
||||
|
||||
|
@ -130,7 +132,8 @@ struct tag_item *tag_pool_dup_item(struct tag_item *item)
|
|||
}
|
||||
}
|
||||
|
||||
void tag_pool_put_item(struct tag_item *item)
|
||||
void
|
||||
tag_pool_put_item(TagItem *item)
|
||||
{
|
||||
struct slot **slot_p, *slot;
|
||||
|
||||
|
|
|
@ -25,13 +25,15 @@
|
|||
|
||||
extern Mutex tag_pool_lock;
|
||||
|
||||
struct tag_item;
|
||||
struct TagItem;
|
||||
|
||||
struct tag_item *
|
||||
TagItem *
|
||||
tag_pool_get_item(enum tag_type type, const char *value, size_t length);
|
||||
|
||||
struct tag_item *tag_pool_dup_item(struct tag_item *item);
|
||||
TagItem *
|
||||
tag_pool_dup_item(TagItem *item);
|
||||
|
||||
void tag_pool_put_item(struct tag_item *item);
|
||||
void
|
||||
tag_pool_put_item(TagItem *item);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "TagPrint.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "TagInternal.hxx"
|
||||
#include "Song.hxx"
|
||||
#include "Client.hxx"
|
||||
|
@ -35,14 +35,14 @@ void tag_print_types(Client *client)
|
|||
}
|
||||
}
|
||||
|
||||
void tag_print(Client *client, const struct tag *tag)
|
||||
void tag_print(Client *client, const Tag &tag)
|
||||
{
|
||||
if (tag->time >= 0)
|
||||
client_printf(client, SONG_TIME "%i\n", tag->time);
|
||||
if (tag.time >= 0)
|
||||
client_printf(client, SONG_TIME "%i\n", tag.time);
|
||||
|
||||
for (unsigned i = 0; i < tag->num_items; i++) {
|
||||
for (unsigned i = 0; i < tag.num_items; i++) {
|
||||
client_printf(client, "%s: %s\n",
|
||||
tag_item_names[tag->items[i]->type],
|
||||
tag->items[i]->value);
|
||||
tag_item_names[tag.items[i]->type],
|
||||
tag.items[i]->value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,11 +20,12 @@
|
|||
#ifndef MPD_TAG_PRINT_HXX
|
||||
#define MPD_TAG_PRINT_HXX
|
||||
|
||||
struct tag;
|
||||
struct Tag;
|
||||
class Client;
|
||||
|
||||
void tag_print_types(Client *client);
|
||||
|
||||
void tag_print(Client *client, const struct tag *tag);
|
||||
void
|
||||
tag_print(Client *client, const Tag &tag);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,20 +19,21 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "TagSave.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "TagInternal.hxx"
|
||||
#include "Song.hxx"
|
||||
|
||||
void tag_save(FILE *file, const struct tag *tag)
|
||||
void
|
||||
tag_save(FILE *file, const Tag &tag)
|
||||
{
|
||||
if (tag->time >= 0)
|
||||
fprintf(file, SONG_TIME "%i\n", tag->time);
|
||||
if (tag.time >= 0)
|
||||
fprintf(file, SONG_TIME "%i\n", tag.time);
|
||||
|
||||
if (tag->has_playlist)
|
||||
if (tag.has_playlist)
|
||||
fprintf(file, "Playlist: yes\n");
|
||||
|
||||
for (unsigned i = 0; i < tag->num_items; i++)
|
||||
for (unsigned i = 0; i < tag.num_items; i++)
|
||||
fprintf(file, "%s: %s\n",
|
||||
tag_item_names[tag->items[i]->type],
|
||||
tag->items[i]->value);
|
||||
tag_item_names[tag.items[i]->type],
|
||||
tag.items[i]->value);
|
||||
}
|
||||
|
|
|
@ -22,8 +22,9 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
struct tag;
|
||||
struct Tag;
|
||||
|
||||
void tag_save(FILE *file, const struct tag *tag);
|
||||
void
|
||||
tag_save(FILE *file, const Tag &tag);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "Mapper.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
#include "TagHandler.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
|
@ -95,7 +95,7 @@ update_container_file(Directory *directory,
|
|||
const Path child_path_fs =
|
||||
map_directory_child_fs(contdir, vtrack);
|
||||
|
||||
song->tag = tag_new();
|
||||
song->tag = new Tag();
|
||||
decoder_plugin_scan_file(plugin, child_path_fs.c_str(),
|
||||
&add_tag_handler, song->tag);
|
||||
|
||||
|
|
|
@ -21,15 +21,16 @@
|
|||
#include "CueParser.hxx"
|
||||
#include "util/StringUtil.hxx"
|
||||
#include "Song.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
CueParser::CueParser()
|
||||
:state(HEADER), tag(tag_new()),
|
||||
:state(HEADER), tag(new Tag()),
|
||||
filename(nullptr),
|
||||
current(nullptr),
|
||||
previous(nullptr),
|
||||
|
@ -38,7 +39,7 @@ CueParser::CueParser()
|
|||
|
||||
CueParser::~CueParser()
|
||||
{
|
||||
tag_free(tag);
|
||||
delete tag;
|
||||
g_free(filename);
|
||||
|
||||
if (current != nullptr)
|
||||
|
@ -109,16 +110,16 @@ cue_next_value(char **pp)
|
|||
}
|
||||
|
||||
static void
|
||||
cue_add_tag(struct tag *tag, enum tag_type type, char *p)
|
||||
cue_add_tag(Tag &tag, enum tag_type type, char *p)
|
||||
{
|
||||
const char *value = cue_next_value(&p);
|
||||
if (value != nullptr)
|
||||
tag_add_item(tag, type, value);
|
||||
tag.AddItem(type, value);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
cue_parse_rem(char *p, struct tag *tag)
|
||||
cue_parse_rem(char *p, Tag &tag)
|
||||
{
|
||||
const char *type = cue_next_token(&p);
|
||||
if (type == nullptr)
|
||||
|
@ -129,7 +130,7 @@ cue_parse_rem(char *p, struct tag *tag)
|
|||
cue_add_tag(tag, type2, p);
|
||||
}
|
||||
|
||||
struct tag *
|
||||
Tag *
|
||||
CueParser::GetCurrentTag()
|
||||
{
|
||||
if (state == HEADER)
|
||||
|
@ -188,9 +189,9 @@ CueParser::Feed2(char *p)
|
|||
return;
|
||||
|
||||
if (strcmp(command, "REM") == 0) {
|
||||
struct tag *current_tag = GetCurrentTag();
|
||||
Tag *current_tag = GetCurrentTag();
|
||||
if (current_tag != nullptr)
|
||||
cue_parse_rem(p, current_tag);
|
||||
cue_parse_rem(p, *current_tag);
|
||||
} else if (strcmp(command, "PERFORMER") == 0) {
|
||||
/* MPD knows a "performer" tag, but it is not a good
|
||||
match for this CUE tag; from the Hydrogenaudio
|
||||
|
@ -202,14 +203,14 @@ CueParser::Feed2(char *p)
|
|||
? TAG_ARTIST
|
||||
: TAG_ALBUM_ARTIST;
|
||||
|
||||
struct tag *current_tag = GetCurrentTag();
|
||||
Tag *current_tag = GetCurrentTag();
|
||||
if (current_tag != nullptr)
|
||||
cue_add_tag(current_tag, type, p);
|
||||
cue_add_tag(*current_tag, type, p);
|
||||
} else if (strcmp(command, "TITLE") == 0) {
|
||||
if (state == HEADER)
|
||||
cue_add_tag(tag, TAG_ALBUM, p);
|
||||
cue_add_tag(*tag, TAG_ALBUM, p);
|
||||
else if (state == TRACK)
|
||||
cue_add_tag(current->tag, TAG_TITLE, p);
|
||||
cue_add_tag(*current->tag, TAG_TITLE, p);
|
||||
} else if (strcmp(command, "FILE") == 0) {
|
||||
Commit();
|
||||
|
||||
|
@ -252,8 +253,8 @@ CueParser::Feed2(char *p)
|
|||
state = TRACK;
|
||||
current = Song::NewRemote(filename);
|
||||
assert(current->tag == nullptr);
|
||||
current->tag = tag_dup(tag);
|
||||
tag_add_item(current->tag, TAG_TRACK, nr);
|
||||
current->tag = new Tag(*tag);
|
||||
current->tag->AddItem(TAG_TRACK, nr);
|
||||
last_updated = false;
|
||||
} else if (state == IGNORE_TRACK) {
|
||||
return;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "gcc.h"
|
||||
|
||||
struct Song;
|
||||
struct Tag;
|
||||
|
||||
class CueParser {
|
||||
enum {
|
||||
|
@ -53,7 +54,7 @@ class CueParser {
|
|||
IGNORE_TRACK,
|
||||
} state;
|
||||
|
||||
struct tag *tag;
|
||||
Tag *tag;
|
||||
|
||||
char *filename;
|
||||
|
||||
|
@ -115,7 +116,7 @@ public:
|
|||
|
||||
private:
|
||||
gcc_pure
|
||||
struct tag *GetCurrentTag();
|
||||
Tag *GetCurrentTag();
|
||||
|
||||
/**
|
||||
* Commit the current song. It will be moved to "previous",
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "Song.hxx"
|
||||
#include "gcc.h"
|
||||
#include "conf.h"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
extern "C" {
|
||||
#include "db_error.h"
|
||||
|
@ -256,7 +256,7 @@ Visit(struct mpd_connection *connection,
|
|||
}
|
||||
|
||||
static void
|
||||
Copy(struct tag *tag, enum tag_type d_tag,
|
||||
Copy(Tag &tag, enum tag_type d_tag,
|
||||
const struct mpd_song *song, enum mpd_tag_type s_tag)
|
||||
{
|
||||
|
||||
|
@ -265,7 +265,7 @@ Copy(struct tag *tag, enum tag_type d_tag,
|
|||
if (value == NULL)
|
||||
break;
|
||||
|
||||
tag_add_item(tag, d_tag, value);
|
||||
tag.AddItem(d_tag, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,13 +278,13 @@ Convert(const struct mpd_song *song)
|
|||
s->start_ms = mpd_song_get_start(song) * 1000;
|
||||
s->end_ms = mpd_song_get_end(song) * 1000;
|
||||
|
||||
struct tag *tag = tag_new();
|
||||
Tag *tag = new Tag();
|
||||
tag->time = mpd_song_get_duration(song);
|
||||
|
||||
tag_begin_add(tag);
|
||||
tag->BeginAdd();
|
||||
for (const auto *i = &tag_table[0]; i->d != TAG_NUM_OF_ITEM_TYPES; ++i)
|
||||
Copy(tag, i->d, song, i->s);
|
||||
tag_end_add(tag);
|
||||
Copy(*tag, i->d, song, i->s);
|
||||
tag->EndAdd();
|
||||
|
||||
s->tag = tag;
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "TagId3.hxx"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h> /* for SEEK_SET, SEEK_CUR */
|
||||
|
||||
#ifdef HAVE_ID3TAG
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <glib.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
|
|
|
@ -43,8 +43,7 @@ flac_data::flac_data(struct decoder *_decoder,
|
|||
|
||||
flac_data::~flac_data()
|
||||
{
|
||||
if (tag != nullptr)
|
||||
tag_free(tag);
|
||||
delete tag;
|
||||
}
|
||||
|
||||
static enum sample_format
|
||||
|
|
|
@ -81,7 +81,7 @@ struct flac_data : public FlacInput {
|
|||
struct decoder *decoder;
|
||||
struct input_stream *input_stream;
|
||||
|
||||
struct tag *tag;
|
||||
Tag *tag;
|
||||
|
||||
flac_data(struct decoder *decoder, struct input_stream *input_stream);
|
||||
~flac_data();
|
||||
|
|
|
@ -172,11 +172,11 @@ flac_decoder_loop(struct flac_data *data, FLAC__StreamDecoder *flac_dec,
|
|||
data->first_frame = t_start;
|
||||
|
||||
while (true) {
|
||||
if (data->tag != nullptr && !tag_is_empty(data->tag)) {
|
||||
if (data->tag != nullptr && !data->tag->IsEmpty()) {
|
||||
cmd = decoder_tag(data->decoder, data->input_stream,
|
||||
data->tag);
|
||||
tag_free(data->tag);
|
||||
data->tag = tag_new();
|
||||
delete data->tag;
|
||||
data->tag = new Tag();
|
||||
} else
|
||||
cmd = decoder_get_command(decoder);
|
||||
|
||||
|
@ -260,7 +260,7 @@ flac_decode_internal(struct decoder * decoder,
|
|||
return;
|
||||
|
||||
struct flac_data data(decoder, input_stream);
|
||||
data.tag = tag_new();
|
||||
data.tag = new Tag();
|
||||
|
||||
FLAC__StreamDecoderInitStatus status =
|
||||
stream_init(flac_dec, &data, is_ogg);
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "config.h"
|
||||
#include "FlacMetadata.hxx"
|
||||
#include "XiphTags.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "TagHandler.hxx"
|
||||
#include "TagTable.hxx"
|
||||
#include "replay_gain_info.h"
|
||||
|
@ -228,7 +228,7 @@ flac_scan_metadata(const FLAC__StreamMetadata *block,
|
|||
}
|
||||
|
||||
void
|
||||
flac_vorbis_comments_to_tag(struct tag *tag,
|
||||
flac_vorbis_comments_to_tag(Tag *tag,
|
||||
const FLAC__StreamMetadata_VorbisComment *comment)
|
||||
{
|
||||
flac_scan_comments(comment, &add_tag_handler, tag);
|
||||
|
|
|
@ -109,7 +109,7 @@ public:
|
|||
};
|
||||
|
||||
struct tag_handler;
|
||||
struct tag;
|
||||
struct Tag;
|
||||
struct replay_gain_info;
|
||||
|
||||
static inline unsigned
|
||||
|
@ -130,7 +130,7 @@ flac_parse_mixramp(char **mixramp_start, char **mixramp_end,
|
|||
const FLAC__StreamMetadata *block);
|
||||
|
||||
void
|
||||
flac_vorbis_comments_to_tag(struct tag *tag,
|
||||
flac_vorbis_comments_to_tag(Tag *tag,
|
||||
const FLAC__StreamMetadata_VorbisComment *comment);
|
||||
|
||||
void
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
#include <mad.h>
|
||||
|
||||
|
@ -143,8 +144,8 @@ struct MadDecoder {
|
|||
|
||||
bool Seek(long offset);
|
||||
bool FillBuffer();
|
||||
void ParseId3(size_t tagsize, struct tag **mpd_tag);
|
||||
enum mp3_action DecodeNextFrameHeader(struct tag **tag);
|
||||
void ParseId3(size_t tagsize, Tag **mpd_tag);
|
||||
enum mp3_action DecodeNextFrameHeader(Tag **tag);
|
||||
enum mp3_action DecodeNextFrame();
|
||||
|
||||
gcc_pure
|
||||
|
@ -158,7 +159,7 @@ struct MadDecoder {
|
|||
*/
|
||||
void FileSizeToSongLength();
|
||||
|
||||
bool DecodeFirstFrame(struct tag **tag);
|
||||
bool DecodeFirstFrame(Tag **tag);
|
||||
|
||||
gcc_pure
|
||||
long TimeToFrame(double t) const;
|
||||
|
@ -334,7 +335,7 @@ parse_id3_mixramp(char **mixramp_start, char **mixramp_end,
|
|||
#endif
|
||||
|
||||
inline void
|
||||
MadDecoder::ParseId3(size_t tagsize, struct tag **mpd_tag)
|
||||
MadDecoder::ParseId3(size_t tagsize, Tag **mpd_tag)
|
||||
{
|
||||
#ifdef HAVE_ID3TAG
|
||||
struct id3_tag *id3_tag = nullptr;
|
||||
|
@ -379,10 +380,9 @@ MadDecoder::ParseId3(size_t tagsize, struct tag **mpd_tag)
|
|||
}
|
||||
|
||||
if (mpd_tag) {
|
||||
struct tag *tmp_tag = tag_id3_import(id3_tag);
|
||||
Tag *tmp_tag = tag_id3_import(id3_tag);
|
||||
if (tmp_tag != nullptr) {
|
||||
if (*mpd_tag != nullptr)
|
||||
tag_free(*mpd_tag);
|
||||
delete *mpd_tag;
|
||||
*mpd_tag = tmp_tag;
|
||||
}
|
||||
}
|
||||
|
@ -453,7 +453,7 @@ id3_tag_query(const void *p0, size_t length)
|
|||
#endif /* !HAVE_ID3TAG */
|
||||
|
||||
enum mp3_action
|
||||
MadDecoder::DecodeNextFrameHeader(struct tag **tag)
|
||||
MadDecoder::DecodeNextFrameHeader(Tag **tag)
|
||||
{
|
||||
if ((stream.buffer == nullptr || stream.error == MAD_ERROR_BUFLEN) &&
|
||||
!FillBuffer())
|
||||
|
@ -807,7 +807,7 @@ MadDecoder::FileSizeToSongLength()
|
|||
}
|
||||
|
||||
inline bool
|
||||
MadDecoder::DecodeFirstFrame(struct tag **tag)
|
||||
MadDecoder::DecodeFirstFrame(Tag **tag)
|
||||
{
|
||||
struct xing xing;
|
||||
struct lame lame;
|
||||
|
@ -1079,13 +1079,13 @@ MadDecoder::Read()
|
|||
bool skip = false;
|
||||
|
||||
do {
|
||||
struct tag *tag = nullptr;
|
||||
Tag *tag = nullptr;
|
||||
|
||||
ret = DecodeNextFrameHeader(&tag);
|
||||
|
||||
if (tag != nullptr) {
|
||||
decoder_tag(decoder, input_stream, tag);
|
||||
tag_free(tag);
|
||||
delete tag;
|
||||
}
|
||||
} while (ret == DECODE_CONT);
|
||||
if (ret == DECODE_BREAK)
|
||||
|
@ -1113,10 +1113,9 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream)
|
|||
{
|
||||
MadDecoder data(decoder, input_stream);
|
||||
|
||||
struct tag *tag = nullptr;
|
||||
Tag *tag = nullptr;
|
||||
if (!data.DecodeFirstFrame(&tag)) {
|
||||
if (tag != nullptr)
|
||||
tag_free(tag);
|
||||
delete tag;
|
||||
|
||||
if (decoder_get_command(decoder) == DECODE_COMMAND_NONE)
|
||||
g_warning
|
||||
|
@ -1134,8 +1133,7 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream)
|
|||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
|
||||
if (tag != nullptr)
|
||||
tag_free(tag);
|
||||
delete tag;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1145,7 +1143,7 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream)
|
|||
|
||||
if (tag != nullptr) {
|
||||
decoder_tag(decoder, input_stream, tag);
|
||||
tag_free(tag);
|
||||
delete tag;
|
||||
}
|
||||
|
||||
while (data.Read()) {}
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include "config.h"
|
||||
#include "OggCodec.hxx"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
enum ogg_codec
|
||||
ogg_codec_detect(struct decoder *decoder, struct input_stream *is)
|
||||
{
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <glib.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
#define G_LOG_DOMAIN "opus"
|
||||
|
@ -221,16 +222,16 @@ MPDOpusDecoder::HandleBOS(const ogg_packet &packet)
|
|||
inline enum decoder_command
|
||||
MPDOpusDecoder::HandleTags(const ogg_packet &packet)
|
||||
{
|
||||
struct tag *tag = tag_new();
|
||||
Tag tag;
|
||||
|
||||
enum decoder_command cmd;
|
||||
if (ScanOpusTags(packet.packet, packet.bytes, &add_tag_handler, tag) &&
|
||||
!tag_is_empty(tag))
|
||||
cmd = decoder_tag(decoder, input_stream, tag);
|
||||
if (ScanOpusTags(packet.packet, packet.bytes,
|
||||
&add_tag_handler, &tag) &&
|
||||
!tag.IsEmpty())
|
||||
cmd = decoder_tag(decoder, input_stream, &tag);
|
||||
else
|
||||
cmd = decoder_get_command(decoder);
|
||||
|
||||
tag_free(tag);
|
||||
return cmd;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ extern "C" {
|
|||
|
||||
#include <glib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h> /* for SEEK_SET */
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "config.h"
|
||||
#include "VorbisComments.hxx"
|
||||
#include "XiphTags.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "TagTable.hxx"
|
||||
#include "TagHandler.hxx"
|
||||
#include "replay_gain_info.h"
|
||||
|
@ -135,14 +135,14 @@ vorbis_comments_scan(char **comments,
|
|||
|
||||
}
|
||||
|
||||
struct tag *
|
||||
Tag *
|
||||
vorbis_comments_to_tag(char **comments)
|
||||
{
|
||||
struct tag *tag = tag_new();
|
||||
Tag *tag = new Tag();
|
||||
vorbis_comments_scan(comments, &add_tag_handler, tag);
|
||||
|
||||
if (tag_is_empty(tag)) {
|
||||
tag_free(tag);
|
||||
if (tag->IsEmpty()) {
|
||||
delete tag;
|
||||
tag = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
struct replay_gain_info;
|
||||
struct tag_handler;
|
||||
struct Tag;
|
||||
|
||||
bool
|
||||
vorbis_comments_to_replay_gain(struct replay_gain_info *rgi, char **comments);
|
||||
|
@ -32,7 +33,7 @@ void
|
|||
vorbis_comments_scan(char **comments,
|
||||
const struct tag_handler *handler, void *handler_ctx);
|
||||
|
||||
struct tag *
|
||||
Tag *
|
||||
vorbis_comments_to_tag(char **comments);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -154,12 +154,12 @@ static void
|
|||
vorbis_send_comments(struct decoder *decoder, struct input_stream *is,
|
||||
char **comments)
|
||||
{
|
||||
struct tag *tag = vorbis_comments_to_tag(comments);
|
||||
Tag *tag = vorbis_comments_to_tag(comments);
|
||||
if (!tag)
|
||||
return;
|
||||
|
||||
decoder_tag(decoder, is, tag);
|
||||
tag_free(tag);
|
||||
delete tag;
|
||||
}
|
||||
|
||||
#ifndef HAVE_TREMOR
|
||||
|
|
|
@ -26,6 +26,7 @@ extern "C" {
|
|||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include <sidplay/sidplay2.h>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "VorbisEncoderPlugin.hxx"
|
||||
#include "OggStream.hxx"
|
||||
#include "EncoderAPI.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "audio_format.h"
|
||||
#include "mpd_error.h"
|
||||
|
||||
|
@ -278,18 +278,18 @@ vorbis_encoder_pre_tag(Encoder *_encoder, G_GNUC_UNUSED GError **error)
|
|||
}
|
||||
|
||||
static void
|
||||
copy_tag_to_vorbis_comment(vorbis_comment *vc, const struct tag *tag)
|
||||
copy_tag_to_vorbis_comment(vorbis_comment *vc, const Tag *tag)
|
||||
{
|
||||
for (unsigned i = 0; i < tag->num_items; i++) {
|
||||
struct tag_item *item = tag->items[i];
|
||||
char *name = g_ascii_strup(tag_item_names[item->type], -1);
|
||||
vorbis_comment_add_tag(vc, name, item->value);
|
||||
const TagItem &item = *tag->items[i];
|
||||
char *name = g_ascii_strup(tag_item_names[item.type], -1);
|
||||
vorbis_comment_add_tag(vc, name, item.value);
|
||||
g_free(name);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
vorbis_encoder_tag(Encoder *_encoder, const struct tag *tag,
|
||||
vorbis_encoder_tag(Encoder *_encoder, const Tag *tag,
|
||||
G_GNUC_UNUSED GError **error)
|
||||
{
|
||||
struct vorbis_encoder *encoder = (struct vorbis_encoder *)_encoder;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "InputStream.hxx"
|
||||
#include "InputPlugin.hxx"
|
||||
#include "conf.h"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "IcyMetaDataParser.hxx"
|
||||
#include "event/MultiSocketMonitor.hxx"
|
||||
#include "event/Loop.hxx"
|
||||
|
@ -160,7 +160,7 @@ struct input_curl {
|
|||
|
||||
/** the tag object ready to be requested via
|
||||
input_stream_tag() */
|
||||
struct tag *tag;
|
||||
Tag *tag;
|
||||
|
||||
GError *postponed_error;
|
||||
|
||||
|
@ -696,8 +696,8 @@ curl_total_buffer_size(const struct input_curl *c)
|
|||
|
||||
input_curl::~input_curl()
|
||||
{
|
||||
if (tag != NULL)
|
||||
tag_free(tag);
|
||||
delete tag;
|
||||
|
||||
g_free(meta_name);
|
||||
|
||||
input_curl_easy_free_indirect(this);
|
||||
|
@ -720,11 +720,11 @@ input_curl_check(struct input_stream *is, GError **error_r)
|
|||
return success;
|
||||
}
|
||||
|
||||
static struct tag *
|
||||
static Tag *
|
||||
input_curl_tag(struct input_stream *is)
|
||||
{
|
||||
struct input_curl *c = (struct input_curl *)is;
|
||||
struct tag *tag = c->tag;
|
||||
Tag *tag = c->tag;
|
||||
|
||||
c->tag = NULL;
|
||||
return tag;
|
||||
|
@ -798,16 +798,15 @@ read_from_buffer(IcyMetaDataParser &icy, std::list<CurlInputBuffer> &buffers,
|
|||
static void
|
||||
copy_icy_tag(struct input_curl *c)
|
||||
{
|
||||
struct tag *tag = c->icy.ReadTag();
|
||||
Tag *tag = c->icy.ReadTag();
|
||||
|
||||
if (tag == NULL)
|
||||
return;
|
||||
|
||||
if (c->tag != NULL)
|
||||
tag_free(c->tag);
|
||||
delete c->tag;
|
||||
|
||||
if (c->meta_name != NULL && !tag_has_type(tag, TAG_NAME))
|
||||
tag_add_item(tag, TAG_NAME, c->meta_name);
|
||||
if (c->meta_name != NULL && !tag->HasType(TAG_NAME))
|
||||
tag->AddItem(TAG_NAME, c->meta_name);
|
||||
|
||||
c->tag = tag;
|
||||
}
|
||||
|
@ -931,11 +930,10 @@ input_curl_headerfunction(void *ptr, size_t size, size_t nmemb, void *stream)
|
|||
g_free(c->meta_name);
|
||||
c->meta_name = g_strndup(value, end - value);
|
||||
|
||||
if (c->tag != NULL)
|
||||
tag_free(c->tag);
|
||||
delete c->tag;
|
||||
|
||||
c->tag = tag_new();
|
||||
tag_add_item(c->tag, TAG_NAME, c->meta_name);
|
||||
c->tag = new Tag();
|
||||
c->tag->AddItem(TAG_NAME, c->meta_name);
|
||||
} else if (g_ascii_strcasecmp(name, "icy-metaint") == 0) {
|
||||
char buffer[64];
|
||||
size_t icy_metaint;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "InputInternal.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "InputPlugin.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
extern "C" {
|
||||
#include <despotify.h>
|
||||
|
@ -42,7 +42,7 @@ struct DespotifyInputStream {
|
|||
|
||||
struct despotify_session *session;
|
||||
struct ds_track *track;
|
||||
struct tag *tag;
|
||||
Tag *tag;
|
||||
struct ds_pcm_data pcm;
|
||||
size_t len_available;
|
||||
bool eof;
|
||||
|
@ -64,8 +64,7 @@ struct DespotifyInputStream {
|
|||
}
|
||||
|
||||
~DespotifyInputStream() {
|
||||
if (tag != NULL)
|
||||
tag_free(tag);
|
||||
delete tag;
|
||||
|
||||
despotify_free_track(track);
|
||||
}
|
||||
|
@ -216,11 +215,11 @@ input_despotify_seek(G_GNUC_UNUSED struct input_stream *is,
|
|||
return false;
|
||||
}
|
||||
|
||||
static struct tag *
|
||||
static Tag *
|
||||
input_despotify_tag(struct input_stream *is)
|
||||
{
|
||||
DespotifyInputStream *ctx = (DespotifyInputStream *)is;
|
||||
struct tag *tag = ctx->tag;
|
||||
Tag *tag = ctx->tag;
|
||||
|
||||
ctx->tag = NULL;
|
||||
|
||||
|
|
|
@ -22,11 +22,12 @@
|
|||
#include "InputInternal.hxx"
|
||||
#include "InputStream.hxx"
|
||||
#include "InputPlugin.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
|
@ -127,7 +128,7 @@ input_rewind_update(struct input_stream *is)
|
|||
r->CopyAttributes();
|
||||
}
|
||||
|
||||
static struct tag *
|
||||
static Tag *
|
||||
input_rewind_tag(struct input_stream *is)
|
||||
{
|
||||
RewindInputStream *r = (RewindInputStream *)is;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
struct Tag;
|
||||
struct input_stream;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -174,12 +175,12 @@ input_stream_lock_eof(struct input_stream *is);
|
|||
*
|
||||
* The caller must lock the mutex.
|
||||
*
|
||||
* @return a tag object which must be freed with tag_free(), or NULL
|
||||
* @return a tag object which must be freed by the caller, or nullptr
|
||||
* if the tag has not changed since the last call
|
||||
*/
|
||||
gcc_nonnull(1)
|
||||
gcc_malloc
|
||||
struct tag *
|
||||
Tag *
|
||||
input_stream_tag(struct input_stream *is);
|
||||
|
||||
/**
|
||||
|
@ -188,7 +189,7 @@ input_stream_tag(struct input_stream *is);
|
|||
*/
|
||||
gcc_nonnull(1)
|
||||
gcc_malloc
|
||||
struct tag *
|
||||
Tag *
|
||||
input_stream_lock_tag(struct input_stream *is);
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <glib.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include <ao/ao.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
#define G_LOG_DOMAIN "ao"
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ class ServerSocket;
|
|||
class HttpdClient;
|
||||
class Page;
|
||||
struct Encoder;
|
||||
struct Tag;
|
||||
|
||||
struct HttpdOutput final : private ServerSocket {
|
||||
struct audio_output base;
|
||||
|
@ -195,7 +196,7 @@ struct HttpdOutput final : private ServerSocket {
|
|||
|
||||
bool EncodeAndPlay(const void *chunk, size_t size, GError **error_r);
|
||||
|
||||
void SendTag(const struct tag *tag);
|
||||
void SendTag(const Tag *tag);
|
||||
|
||||
private:
|
||||
virtual void OnAccept(int fd, const sockaddr &address,
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_LIBWRAP
|
||||
|
@ -484,7 +485,7 @@ httpd_output_pause(struct audio_output *ao)
|
|||
}
|
||||
|
||||
inline void
|
||||
HttpdOutput::SendTag(const struct tag *tag)
|
||||
HttpdOutput::SendTag(const Tag *tag)
|
||||
{
|
||||
assert(tag != NULL);
|
||||
|
||||
|
@ -523,7 +524,7 @@ HttpdOutput::SendTag(const struct tag *tag)
|
|||
TAG_NUM_OF_ITEM_TYPES
|
||||
};
|
||||
|
||||
metadata = icy_server_metadata_page(tag, &types[0]);
|
||||
metadata = icy_server_metadata_page(*tag, &types[0]);
|
||||
if (metadata != NULL) {
|
||||
const ScopeLock protect(mutex);
|
||||
for (auto &client : clients)
|
||||
|
@ -533,7 +534,7 @@ HttpdOutput::SendTag(const struct tag *tag)
|
|||
}
|
||||
|
||||
static void
|
||||
httpd_output_tag(struct audio_output *ao, const struct tag *tag)
|
||||
httpd_output_tag(struct audio_output *ao, const Tag *tag)
|
||||
{
|
||||
HttpdOutput *httpd = Cast(ao);
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <jack/ringbuffer.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
|
|
@ -329,7 +329,7 @@ roar_tag_convert(enum tag_type type, bool *is_uuid)
|
|||
}
|
||||
|
||||
static void
|
||||
roar_send_tag(struct audio_output *ao, const struct tag *meta)
|
||||
roar_send_tag(struct audio_output *ao, const Tag *meta)
|
||||
{
|
||||
RoarOutput *self = (RoarOutput *)ao;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#undef G_LOG_DOMAIN
|
||||
|
@ -482,7 +483,7 @@ my_shout_pause(struct audio_output *ao)
|
|||
}
|
||||
|
||||
static void
|
||||
shout_tag_to_metadata(const struct tag *tag, char *dest, size_t size)
|
||||
shout_tag_to_metadata(const Tag *tag, char *dest, size_t size)
|
||||
{
|
||||
char artist[size];
|
||||
char title[size];
|
||||
|
@ -508,7 +509,7 @@ shout_tag_to_metadata(const struct tag *tag, char *dest, size_t size)
|
|||
}
|
||||
|
||||
static void my_shout_set_tag(struct audio_output *ao,
|
||||
const struct tag *tag)
|
||||
const Tag *tag)
|
||||
{
|
||||
ShoutOutput *sd = (ShoutOutput *)ao;
|
||||
GError *error = nullptr;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "MemoryPlaylistProvider.hxx"
|
||||
#include "input_stream.h"
|
||||
#include "Song.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
|
@ -169,9 +169,9 @@ asx_text(G_GNUC_UNUSED GMarkupParseContext *context,
|
|||
case AsxParser::ENTRY:
|
||||
if (parser->tag != TAG_NUM_OF_ITEM_TYPES) {
|
||||
if (parser->song->tag == NULL)
|
||||
parser->song->tag = tag_new();
|
||||
tag_add_item_n(parser->song->tag, parser->tag,
|
||||
text, text_len);
|
||||
parser->song->tag = new Tag();
|
||||
parser->song->tag->AddItem(parser->tag,
|
||||
text, text_len);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "config.h"
|
||||
#include "CuePlaylistPlugin.hxx"
|
||||
#include "PlaylistPlugin.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "Song.hxx"
|
||||
#include "input_stream.h"
|
||||
#include "cue/CueParser.hxx"
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "DespotifyPlaylistPlugin.hxx"
|
||||
#include "DespotifyUtils.hxx"
|
||||
#include "MemoryPlaylistProvider.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "Song.hxx"
|
||||
|
||||
extern "C" {
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "config.h"
|
||||
#include "EmbeddedCuePlaylistPlugin.hxx"
|
||||
#include "PlaylistPlugin.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "TagHandler.hxx"
|
||||
#include "TagId3.hxx"
|
||||
#include "ApeTag.hxx"
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "ExtM3uPlaylistPlugin.hxx"
|
||||
#include "PlaylistPlugin.hxx"
|
||||
#include "Song.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "util/StringUtil.hxx"
|
||||
#include "TextInputStream.hxx"
|
||||
|
||||
|
@ -70,13 +70,13 @@ extm3u_close(struct playlist_provider *_playlist)
|
|||
*
|
||||
* @param line the rest of the input line after the colon
|
||||
*/
|
||||
static struct tag *
|
||||
static Tag *
|
||||
extm3u_parse_tag(const char *line)
|
||||
{
|
||||
long duration;
|
||||
char *endptr;
|
||||
const char *name;
|
||||
struct tag *tag;
|
||||
Tag *tag;
|
||||
|
||||
duration = strtol(line, &endptr, 10);
|
||||
if (endptr[0] != ',')
|
||||
|
@ -93,14 +93,14 @@ extm3u_parse_tag(const char *line)
|
|||
object */
|
||||
return NULL;
|
||||
|
||||
tag = tag_new();
|
||||
tag = new Tag();
|
||||
tag->time = duration;
|
||||
|
||||
/* unfortunately, there is no real specification for the
|
||||
EXTM3U format, so we must assume that the string after the
|
||||
comma is opaque, and is just the song name*/
|
||||
if (*name != 0)
|
||||
tag_add_item(tag, TAG_NAME, name);
|
||||
tag->AddItem(TAG_NAME, name);
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
@ -109,23 +109,21 @@ static Song *
|
|||
extm3u_read(struct playlist_provider *_playlist)
|
||||
{
|
||||
ExtM3uPlaylist *playlist = (ExtM3uPlaylist *)_playlist;
|
||||
struct tag *tag = NULL;
|
||||
Tag *tag = NULL;
|
||||
std::string line;
|
||||
const char *line_s;
|
||||
Song *song;
|
||||
|
||||
do {
|
||||
if (!playlist->tis->ReadLine(line)) {
|
||||
if (tag != NULL)
|
||||
tag_free(tag);
|
||||
delete tag;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
line_s = line.c_str();
|
||||
|
||||
if (g_str_has_prefix(line_s, "#EXTINF:")) {
|
||||
if (tag != NULL)
|
||||
tag_free(tag);
|
||||
delete tag;
|
||||
tag = extm3u_parse_tag(line_s + 8);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "MemoryPlaylistProvider.hxx"
|
||||
#include "input_stream.h"
|
||||
#include "Song.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
|
@ -71,8 +71,8 @@ pls_parser(GKeyFile *keyfile, std::forward_list<SongPointer> &songs)
|
|||
g_free(key);
|
||||
if(error == NULL && value){
|
||||
if (song->tag == NULL)
|
||||
song->tag = tag_new();
|
||||
tag_add_item(song->tag,TAG_TITLE, value);
|
||||
song->tag = new Tag();
|
||||
song->tag->AddItem(TAG_TITLE, value);
|
||||
}
|
||||
/* Ignore errors? Most likely value not present */
|
||||
if(error) g_error_free(error);
|
||||
|
@ -85,7 +85,7 @@ pls_parser(GKeyFile *keyfile, std::forward_list<SongPointer> &songs)
|
|||
g_free(key);
|
||||
if(error == NULL && length > 0){
|
||||
if (song->tag == NULL)
|
||||
song->tag = tag_new();
|
||||
song->tag = new Tag();
|
||||
song->tag->time = length;
|
||||
}
|
||||
/* Ignore errors? Most likely value not present */
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "MemoryPlaylistProvider.hxx"
|
||||
#include "input_stream.h"
|
||||
#include "Song.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
|
@ -166,9 +166,9 @@ rss_text(G_GNUC_UNUSED GMarkupParseContext *context,
|
|||
case RssParser::ITEM:
|
||||
if (parser->tag != TAG_NUM_OF_ITEM_TYPES) {
|
||||
if (parser->song->tag == NULL)
|
||||
parser->song->tag = tag_new();
|
||||
tag_add_item_n(parser->song->tag, parser->tag,
|
||||
text, text_len);
|
||||
parser->song->tag = new Tag();
|
||||
parser->song->tag->AddItem(parser->tag,
|
||||
text, text_len);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "conf.h"
|
||||
#include "input_stream.h"
|
||||
#include "Song.hxx"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
#include <yajl/yajl_parse.h>
|
||||
|
@ -204,16 +204,16 @@ static int handle_end_map(void *ctx)
|
|||
data->got_url = 0;
|
||||
|
||||
Song *s;
|
||||
struct tag *t;
|
||||
char *u;
|
||||
|
||||
u = g_strconcat(data->stream_url, "?client_id=", soundcloud_config.apikey, NULL);
|
||||
s = Song::NewRemote(u);
|
||||
g_free(u);
|
||||
t = tag_new();
|
||||
|
||||
Tag *t = new Tag();
|
||||
t->time = data->duration / 1000;
|
||||
if (data->title != NULL)
|
||||
tag_add_item(t, TAG_NAME, data->title);
|
||||
t->AddItem(TAG_NAME, data->title);
|
||||
s->tag = t;
|
||||
|
||||
data->songs.emplace_front(s);
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "XspfPlaylistPlugin.hxx"
|
||||
#include "MemoryPlaylistProvider.hxx"
|
||||
#include "input_stream.h"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
|
@ -177,9 +177,8 @@ xspf_text(G_GNUC_UNUSED GMarkupParseContext *context,
|
|||
if (parser->song != NULL &&
|
||||
parser->tag != TAG_NUM_OF_ITEM_TYPES) {
|
||||
if (parser->song->tag == NULL)
|
||||
parser->song->tag = tag_new();
|
||||
tag_add_item_n(parser->song->tag, parser->tag,
|
||||
text, text_len);
|
||||
parser->song->tag = new Tag();
|
||||
parser->song->tag->AddItem(parser->tag, text, text_len);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
215
src/tag.h
215
src/tag.h
|
@ -1,215 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2003-2013 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPD_TAG_H
|
||||
#define MPD_TAG_H
|
||||
|
||||
#include "TagType.h"
|
||||
#include "gcc.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* One tag value. It is a mapping of #tag_type to am arbitrary string
|
||||
* value. Each tag can have multiple items of one tag type (although
|
||||
* few clients support that).
|
||||
*/
|
||||
struct tag_item {
|
||||
/** the type of this item */
|
||||
enum tag_type type;
|
||||
|
||||
/**
|
||||
* the value of this tag; this is a variable length string
|
||||
*/
|
||||
char value[sizeof(long)];
|
||||
} gcc_packed;
|
||||
|
||||
/**
|
||||
* The meta information about a song file. It is a MPD specific
|
||||
* subset of tags (e.g. from ID3, vorbis comments, ...).
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
int time;
|
||||
|
||||
/**
|
||||
* Does this file have an embedded playlist (e.g. embedded CUE
|
||||
* sheet)?
|
||||
*/
|
||||
bool has_playlist;
|
||||
|
||||
/** an array of tag items */
|
||||
struct tag_item **items;
|
||||
|
||||
/** the total number of tag items in the #items array */
|
||||
unsigned num_items;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Parse the string, and convert it into a #tag_type. Returns
|
||||
* #TAG_NUM_OF_ITEM_TYPES if the string could not be recognized.
|
||||
*/
|
||||
enum tag_type
|
||||
tag_name_parse(const char *name);
|
||||
|
||||
/**
|
||||
* Parse the string, and convert it into a #tag_type. Returns
|
||||
* #TAG_NUM_OF_ITEM_TYPES if the string could not be recognized.
|
||||
*
|
||||
* Case does not matter.
|
||||
*/
|
||||
enum tag_type
|
||||
tag_name_parse_i(const char *name);
|
||||
|
||||
/**
|
||||
* Creates an empty #tag.
|
||||
*/
|
||||
struct tag *tag_new(void);
|
||||
|
||||
/**
|
||||
* Initializes the tag library.
|
||||
*/
|
||||
void tag_lib_init(void);
|
||||
|
||||
/**
|
||||
* Clear all tag items with the specified type.
|
||||
*/
|
||||
void tag_clear_items_by_type(struct tag *tag, enum tag_type type);
|
||||
|
||||
/**
|
||||
* Frees a #tag object and all its items.
|
||||
*/
|
||||
void tag_free(struct tag *tag);
|
||||
|
||||
/**
|
||||
* Gives an optional hint to the tag library that we will now add
|
||||
* several tag items; this is used by the library to optimize memory
|
||||
* allocation. Only one tag may be in this state, and this tag must
|
||||
* not have any items yet. You must call tag_end_add() when you are
|
||||
* done.
|
||||
*/
|
||||
void tag_begin_add(struct tag *tag);
|
||||
|
||||
/**
|
||||
* Finishes the operation started with tag_begin_add().
|
||||
*/
|
||||
void tag_end_add(struct tag *tag);
|
||||
|
||||
/**
|
||||
* 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 (not null-terminated)
|
||||
* @param len the length of #value
|
||||
*/
|
||||
void tag_add_item_n(struct tag *tag, enum tag_type 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)
|
||||
*/
|
||||
static inline void
|
||||
tag_add_item(struct tag *tag, enum tag_type type, const char *value)
|
||||
{
|
||||
tag_add_item_n(tag, type, value, strlen(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicates a #tag object.
|
||||
*/
|
||||
struct tag *tag_dup(const struct tag *tag);
|
||||
|
||||
/**
|
||||
* Merges the data from two tags. If both tags share data for the
|
||||
* same tag_type, only data from "add" is used.
|
||||
*
|
||||
* @return a newly allocated tag, which must be freed with tag_free()
|
||||
*/
|
||||
struct tag *
|
||||
tag_merge(const struct tag *base, const struct tag *add);
|
||||
|
||||
/**
|
||||
* Merges the data from two tags. Any of the two may be NULL. Both
|
||||
* are freed by this function.
|
||||
*
|
||||
* @return a newly allocated tag, which must be freed with tag_free()
|
||||
*/
|
||||
struct tag *
|
||||
tag_merge_replace(struct tag *base, struct tag *add);
|
||||
|
||||
/**
|
||||
* Returns true if the tag contains no items. This ignores the "time"
|
||||
* attribute.
|
||||
*/
|
||||
static inline bool
|
||||
tag_is_empty(const struct tag *tag)
|
||||
{
|
||||
return tag->num_items == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the tag contains any information.
|
||||
*/
|
||||
static inline bool
|
||||
tag_is_defined(const struct tag *tag)
|
||||
{
|
||||
return !tag_is_empty(tag) || tag->time >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first value of the specified tag type, or NULL if none
|
||||
* is present in this tag object.
|
||||
*/
|
||||
const char *
|
||||
tag_get_value(const struct tag *tag, enum tag_type type);
|
||||
|
||||
/**
|
||||
* Checks whether the tag contains one or more items with
|
||||
* the specified type.
|
||||
*/
|
||||
bool tag_has_type(const struct tag *tag, enum tag_type type);
|
||||
|
||||
/**
|
||||
* Compares two tags, including the duration and all tag items. The
|
||||
* order of the tag items matters.
|
||||
*/
|
||||
bool tag_equal(const struct tag *tag1, const struct tag *tag2);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -25,7 +25,7 @@
|
|||
#include "Song.hxx"
|
||||
#include "PlaylistVector.hxx"
|
||||
#include "conf.h"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
|
||||
#include <iostream>
|
||||
|
|
|
@ -106,7 +106,7 @@ decoder_data(G_GNUC_UNUSED struct decoder *decoder,
|
|||
enum decoder_command
|
||||
decoder_tag(G_GNUC_UNUSED struct decoder *decoder,
|
||||
G_GNUC_UNUSED struct input_stream *is,
|
||||
G_GNUC_UNUSED const struct tag *tag)
|
||||
G_GNUC_UNUSED const Tag *tag)
|
||||
{
|
||||
return DECODE_COMMAND_NONE;
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ int main(int argc, char **argv)
|
|||
(song->start_ms / 1000) % 60);
|
||||
|
||||
if (song->tag != NULL)
|
||||
tag_save(stdout, song->tag);
|
||||
tag_save(stdout, *song->tag);
|
||||
|
||||
song->Free();
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "TagRva2.hxx"
|
||||
#include "replay_gain_info.h"
|
||||
#include "conf.h"
|
||||
#include "tag.h"
|
||||
#include "Tag.hxx"
|
||||
|
||||
#include <id3tag.h>
|
||||
|
||||
|
@ -41,23 +41,13 @@ config_get_string(gcc_unused enum ConfigOption option,
|
|||
return default_value;
|
||||
}
|
||||
|
||||
struct tag *
|
||||
tag_new(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
tag_add_item_n(gcc_unused struct tag *tag, gcc_unused enum tag_type type,
|
||||
gcc_unused const char *value, gcc_unused size_t len)
|
||||
Tag::AddItem(gcc_unused enum tag_type type,
|
||||
gcc_unused const char *value)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
tag_free(struct tag *tag)
|
||||
{
|
||||
g_free(tag);
|
||||
}
|
||||
Tag::~Tag() {}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue