Commit 52ee132d authored by Max Kellermann's avatar Max Kellermann

TagHandler: use a TagBuilder internally

Reduce heap allocator overhead.
parent 7ca0aedc
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "DecoderPlugin.hxx" #include "DecoderPlugin.hxx"
#include "DecoderList.hxx" #include "DecoderList.hxx"
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "tag/TagBuilder.hxx"
#include "tag/TagHandler.hxx" #include "tag/TagHandler.hxx"
#include "tag/TagId3.hxx" #include "tag/TagId3.hxx"
#include "tag/ApeTag.hxx" #include "tag/ApeTag.hxx"
...@@ -113,15 +114,15 @@ Song::UpdateFile() ...@@ -113,15 +114,15 @@ Song::UpdateFile()
Mutex mutex; Mutex mutex;
Cond cond; Cond cond;
TagBuilder tag_builder;
do { do {
/* load file tag */ /* load file tag */
tag = new Tag();
if (decoder_plugin_scan_file(plugin, path_fs.c_str(), if (decoder_plugin_scan_file(plugin, path_fs.c_str(),
&full_tag_handler, tag)) &full_tag_handler, &tag_builder))
break; break;
delete tag; tag_builder.Clear();
tag = nullptr;
/* fall back to stream tag */ /* fall back to stream tag */
if (plugin->scan_stream != NULL) { if (plugin->scan_stream != NULL) {
...@@ -134,14 +135,12 @@ Song::UpdateFile() ...@@ -134,14 +135,12 @@ Song::UpdateFile()
/* now try the stream_tag() method */ /* now try the stream_tag() method */
if (is != NULL) { if (is != NULL) {
tag = new Tag();
if (decoder_plugin_scan_stream(plugin, is, if (decoder_plugin_scan_stream(plugin, is,
&full_tag_handler, &full_tag_handler,
tag)) &tag_builder))
break; break;
delete tag; tag_builder.Clear();
tag = nullptr;
is->LockSeek(0, SEEK_SET, IgnoreError()); is->LockSeek(0, SEEK_SET, IgnoreError());
} }
...@@ -153,10 +152,15 @@ Song::UpdateFile() ...@@ -153,10 +152,15 @@ Song::UpdateFile()
if (is != NULL) if (is != NULL)
is->Close(); is->Close();
if (tag != nullptr && tag->IsEmpty()) if (!tag_builder.IsDefined())
tag_scan_fallback(path_fs.c_str(), &full_tag_handler, tag); return false;
if (tag_builder.IsEmpty())
tag_scan_fallback(path_fs.c_str(), &full_tag_handler,
&tag_builder);
return tag != nullptr; tag = tag_builder.Commit();
return true;
} }
bool bool
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include "Mapper.hxx" #include "Mapper.hxx"
#include "fs/Path.hxx" #include "fs/Path.hxx"
#include "tag/TagHandler.hxx" #include "tag/TagHandler.hxx"
#include "tag/Tag.hxx" #include "tag/TagBuilder.hxx"
#include <glib.h> #include <glib.h>
...@@ -86,6 +86,7 @@ update_container_file(Directory *directory, ...@@ -86,6 +86,7 @@ update_container_file(Directory *directory,
char *vtrack; char *vtrack;
unsigned int tnum = 0; unsigned int tnum = 0;
TagBuilder tag_builder;
while ((vtrack = plugin->container_scan(pathname.c_str(), ++tnum)) != NULL) { while ((vtrack = plugin->container_scan(pathname.c_str(), ++tnum)) != NULL) {
Song *song = Song::NewFile(vtrack, contdir); Song *song = Song::NewFile(vtrack, contdir);
...@@ -95,9 +96,13 @@ update_container_file(Directory *directory, ...@@ -95,9 +96,13 @@ update_container_file(Directory *directory,
const Path child_path_fs = const Path child_path_fs =
map_directory_child_fs(contdir, vtrack); map_directory_child_fs(contdir, vtrack);
song->tag = new Tag();
decoder_plugin_scan_file(plugin, child_path_fs.c_str(), decoder_plugin_scan_file(plugin, child_path_fs.c_str(),
&add_tag_handler, song->tag); &add_tag_handler, &tag_builder);
if (tag_builder.IsDefined())
song->tag = tag_builder.Commit();
else
tag_builder.Clear();
db_lock(); db_lock();
contdir->AddSong(song); contdir->AddSong(song);
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "tag/TagHandler.hxx" #include "tag/TagHandler.hxx"
#include "tag/TagTable.hxx" #include "tag/TagTable.hxx"
#include "tag/TagBuilder.hxx"
#include "replay_gain_info.h" #include "replay_gain_info.h"
#include <glib.h> #include <glib.h>
...@@ -231,7 +232,9 @@ void ...@@ -231,7 +232,9 @@ void
flac_vorbis_comments_to_tag(Tag &tag, flac_vorbis_comments_to_tag(Tag &tag,
const FLAC__StreamMetadata_VorbisComment *comment) const FLAC__StreamMetadata_VorbisComment *comment)
{ {
flac_scan_comments(comment, &add_tag_handler, &tag); TagBuilder tag_builder;
flac_scan_comments(comment, &add_tag_handler, &tag_builder);
tag_builder.Commit(tag);
} }
void void
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "OggCodec.hxx" #include "OggCodec.hxx"
#include "CheckAudioFormat.hxx" #include "CheckAudioFormat.hxx"
#include "tag/TagHandler.hxx" #include "tag/TagHandler.hxx"
#include "tag/TagBuilder.hxx"
#include "InputStream.hxx" #include "InputStream.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
...@@ -222,14 +223,16 @@ MPDOpusDecoder::HandleBOS(const ogg_packet &packet) ...@@ -222,14 +223,16 @@ MPDOpusDecoder::HandleBOS(const ogg_packet &packet)
inline enum decoder_command inline enum decoder_command
MPDOpusDecoder::HandleTags(const ogg_packet &packet) MPDOpusDecoder::HandleTags(const ogg_packet &packet)
{ {
Tag tag; TagBuilder tag_builder;
enum decoder_command cmd; enum decoder_command cmd;
if (ScanOpusTags(packet.packet, packet.bytes, if (ScanOpusTags(packet.packet, packet.bytes,
&add_tag_handler, &tag) && &add_tag_handler, &tag_builder) &&
!tag.IsEmpty()) !tag_builder.IsEmpty()) {
Tag tag;
tag_builder.Commit(tag);
cmd = decoder_tag(decoder, input_stream, std::move(tag)); cmd = decoder_tag(decoder, input_stream, std::move(tag));
else } else
cmd = decoder_get_command(decoder); cmd = decoder_get_command(decoder);
return cmd; return cmd;
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "tag/TagTable.hxx" #include "tag/TagTable.hxx"
#include "tag/TagHandler.hxx" #include "tag/TagHandler.hxx"
#include "tag/TagBuilder.hxx"
#include "replay_gain_info.h" #include "replay_gain_info.h"
#include <glib.h> #include <glib.h>
...@@ -138,13 +139,9 @@ vorbis_comments_scan(char **comments, ...@@ -138,13 +139,9 @@ vorbis_comments_scan(char **comments,
Tag * Tag *
vorbis_comments_to_tag(char **comments) vorbis_comments_to_tag(char **comments)
{ {
Tag *tag = new Tag(); TagBuilder tag_builder;
vorbis_comments_scan(comments, &add_tag_handler, tag); vorbis_comments_scan(comments, &add_tag_handler, &tag_builder);
return tag_builder.IsEmpty()
if (tag->IsEmpty()) { ? nullptr
delete tag; : tag_builder.Commit();
tag = NULL;
}
return tag;
} }
...@@ -19,24 +19,24 @@ ...@@ -19,24 +19,24 @@
#include "config.h" #include "config.h"
#include "TagHandler.hxx" #include "TagHandler.hxx"
#include "Tag.hxx" #include "TagBuilder.hxx"
#include <glib.h> #include <glib.h>
static void static void
add_tag_duration(unsigned seconds, void *ctx) add_tag_duration(unsigned seconds, void *ctx)
{ {
Tag *tag = (Tag *)ctx; TagBuilder &tag = *(TagBuilder *)ctx;
tag->time = seconds; tag.SetTime(seconds);
} }
static void static void
add_tag_tag(enum tag_type type, const char *value, void *ctx) add_tag_tag(enum tag_type type, const char *value, void *ctx)
{ {
Tag *tag = (Tag *)ctx; TagBuilder &tag = *(TagBuilder *)ctx;
tag->AddItem(type, value); tag.AddItem(type, value);
} }
const struct tag_handler add_tag_handler = { const struct tag_handler add_tag_handler = {
...@@ -48,10 +48,10 @@ const struct tag_handler add_tag_handler = { ...@@ -48,10 +48,10 @@ const struct tag_handler add_tag_handler = {
static void static void
full_tag_pair(const char *name, gcc_unused const char *value, void *ctx) full_tag_pair(const char *name, gcc_unused const char *value, void *ctx)
{ {
Tag *tag = (Tag *)ctx; TagBuilder &tag = *(TagBuilder *)ctx;
if (g_ascii_strcasecmp(name, "cuesheet") == 0) if (g_ascii_strcasecmp(name, "cuesheet") == 0)
tag->has_playlist = true; tag.SetHasPlaylist(true);
} }
const struct tag_handler full_tag_handler = { const struct tag_handler full_tag_handler = {
......
...@@ -86,13 +86,13 @@ tag_handler_invoke_pair(const struct tag_handler *handler, void *ctx, ...@@ -86,13 +86,13 @@ tag_handler_invoke_pair(const struct tag_handler *handler, void *ctx,
} }
/** /**
* This #tag_handler implementation adds tag values to a #tag object * This #tag_handler implementation adds tag values to a #TagBuilder object
* (casted from the context pointer). * (casted from the context pointer).
*/ */
extern const struct tag_handler add_tag_handler; extern const struct tag_handler add_tag_handler;
/** /**
* This #tag_handler implementation adds tag values to a #tag object * This #tag_handler implementation adds tag values to a #TagBuilder object
* (casted from the context pointer), and supports the has_playlist * (casted from the context pointer), and supports the has_playlist
* attribute. * attribute.
*/ */
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "TagHandler.hxx" #include "TagHandler.hxx"
#include "TagTable.hxx" #include "TagTable.hxx"
#include "Tag.hxx" #include "Tag.hxx"
#include "TagBuilder.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
#include "ConfigGlobal.hxx" #include "ConfigGlobal.hxx"
...@@ -387,16 +388,11 @@ scan_id3_tag(struct id3_tag *tag, ...@@ -387,16 +388,11 @@ scan_id3_tag(struct id3_tag *tag,
Tag * Tag *
tag_id3_import(struct id3_tag *tag) tag_id3_import(struct id3_tag *tag)
{ {
Tag *ret = new Tag(); TagBuilder tag_builder;
scan_id3_tag(tag, &add_tag_handler, &tag_builder);
scan_id3_tag(tag, &add_tag_handler, ret); return tag_builder.IsEmpty()
? nullptr
if (ret->IsEmpty()) { : tag_builder.Commit();
delete ret;
ret = nullptr;
}
return ret;
} }
static int static int
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment