Commit 2c2efaa9 authored by Max Kellermann's avatar Max Kellermann

lib/xiph/VorbisComments: pass struct vorbis_comment instead of char**

Use the "comments" attribute instead of relying on the nullptr terminator.
parent 9ae9b2c1
...@@ -157,10 +157,10 @@ VorbisDecoder::OnOggBeginning(const ogg_packet &_packet) ...@@ -157,10 +157,10 @@ VorbisDecoder::OnOggBeginning(const ogg_packet &_packet)
} }
static void static void
vorbis_send_comments(DecoderClient &client, InputStream &is, SubmitVorbisComment(DecoderClient &client, InputStream &is,
char **comments) const vorbis_comment &vc)
{ {
auto tag = vorbis_comments_to_tag(comments); auto tag = VorbisCommentToTag(vc);
if (!tag) if (!tag)
return; return;
...@@ -269,10 +269,10 @@ VorbisDecoder::OnOggPacket(const ogg_packet &_packet) ...@@ -269,10 +269,10 @@ VorbisDecoder::OnOggPacket(const ogg_packet &_packet)
} else } else
SubmitInit(); SubmitInit();
vorbis_send_comments(client, input_stream, vc.user_comments); SubmitVorbisComment(client, input_stream, vc);
ReplayGainInfo rgi; ReplayGainInfo rgi;
if (vorbis_comments_to_replay_gain(rgi, vc.user_comments)) if (VorbisCommentToReplayGain(rgi, vc))
client.SubmitReplayGain(&rgi); client.SubmitReplayGain(&rgi);
} else { } else {
if (!dsp_initialized) { if (!dsp_initialized) {
...@@ -404,7 +404,7 @@ vorbis_scan_stream(InputStream &is, TagHandler &handler) noexcept ...@@ -404,7 +404,7 @@ vorbis_scan_stream(InputStream &is, TagHandler &handler) noexcept
/* visit the Vorbis comments we just read */ /* visit the Vorbis comments we just read */
vorbis_comments_scan(vc.user_comments, handler); VorbisCommentScan(vc, handler);
/* check the song duration by locating the e_o_s packet */ /* check the song duration by locating the e_o_s packet */
......
...@@ -27,20 +27,38 @@ ...@@ -27,20 +27,38 @@
#include "tag/ReplayGain.hxx" #include "tag/ReplayGain.hxx"
#include "ReplayGainInfo.hxx" #include "ReplayGainInfo.hxx"
#include "util/StringView.hxx" #include "util/StringView.hxx"
#include "config.h"
#ifndef HAVE_TREMOR
#include <vorbis/codec.h>
#else
#include <tremor/ivorbiscodec.h>
#endif /* HAVE_TREMOR */
template<typename F>
static void
ForEachUserComment(const vorbis_comment &vc, F &&f)
{
const char *const*const user_comments = vc.user_comments;
const int*const comment_lengths = vc.comment_lengths;
const size_t n = vc.comments;
for (size_t i = 0; i < n; ++i)
f(StringView{user_comments[i], size_t(comment_lengths[i])});
}
bool bool
vorbis_comments_to_replay_gain(ReplayGainInfo &rgi, char **comments) noexcept VorbisCommentToReplayGain(ReplayGainInfo &rgi,
const vorbis_comment &vc) noexcept
{ {
rgi.Clear(); rgi.Clear();
bool found = false; bool found = false;
while (*comments) { ForEachUserComment(vc, [&](StringView s){
if (ParseReplayGainVorbis(rgi, *comments)) if (ParseReplayGainVorbis(rgi, s.data))
found = true; found = true;
});
comments++;
}
return found; return found;
} }
...@@ -64,10 +82,10 @@ vorbis_copy_comment(StringView comment, ...@@ -64,10 +82,10 @@ vorbis_copy_comment(StringView comment,
} }
static void static void
vorbis_scan_comment(const char *comment, TagHandler &handler) noexcept vorbis_scan_comment(StringView comment, TagHandler &handler) noexcept
{ {
if (handler.WantPair()) { if (handler.WantPair()) {
const auto split = StringView(comment).Split('='); const auto split = comment.Split('=');
if (!split.first.empty() && !split.second.IsNull()) if (!split.first.empty() && !split.second.IsNull())
handler.OnPair(split.first, split.second); handler.OnPair(split.first, split.second);
} }
...@@ -85,19 +103,19 @@ vorbis_scan_comment(const char *comment, TagHandler &handler) noexcept ...@@ -85,19 +103,19 @@ vorbis_scan_comment(const char *comment, TagHandler &handler) noexcept
} }
void void
vorbis_comments_scan(char **comments, TagHandler &handler) noexcept VorbisCommentScan(const vorbis_comment &vc, TagHandler &handler) noexcept
{ {
while (*comments) ForEachUserComment(vc, [&](StringView s){
vorbis_scan_comment(*comments++, handler); vorbis_scan_comment(s, handler);
});
} }
std::unique_ptr<Tag> std::unique_ptr<Tag>
vorbis_comments_to_tag(char **comments) noexcept VorbisCommentToTag(const vorbis_comment &vc) noexcept
{ {
TagBuilder tag_builder; TagBuilder tag_builder;
AddTagHandler h(tag_builder); AddTagHandler h(tag_builder);
vorbis_comments_scan(comments, h); VorbisCommentScan(vc, h);
return tag_builder.empty() return tag_builder.empty()
? nullptr ? nullptr
: tag_builder.CommitNew(); : tag_builder.CommitNew();
......
...@@ -22,17 +22,19 @@ ...@@ -22,17 +22,19 @@
#include <memory> #include <memory>
struct vorbis_comment;
struct ReplayGainInfo; struct ReplayGainInfo;
class TagHandler; class TagHandler;
struct Tag; struct Tag;
bool bool
vorbis_comments_to_replay_gain(ReplayGainInfo &rgi, char **comments) noexcept; VorbisCommentToReplayGain(ReplayGainInfo &rgi,
const vorbis_comment &vc) noexcept;
void void
vorbis_comments_scan(char **comments, TagHandler &handler) noexcept; VorbisCommentScan(const vorbis_comment &vc, TagHandler &handler) noexcept;
std::unique_ptr<Tag> std::unique_ptr<Tag>
vorbis_comments_to_tag(char **comments) noexcept; VorbisCommentToTag(const vorbis_comment &vc) noexcept;
#endif #endif
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