tag/IcyMetadataParser: pass std::string_view to icy_parse_tag()
This commit is contained in:
parent
e443ee357a
commit
58fc857a2d
|
@ -4,6 +4,7 @@
|
||||||
#include "IcyMetaDataParser.hxx"
|
#include "IcyMetaDataParser.hxx"
|
||||||
#include "tag/Builder.hxx"
|
#include "tag/Builder.hxx"
|
||||||
#include "util/AllocatedString.hxx"
|
#include "util/AllocatedString.hxx"
|
||||||
|
#include "util/StringSplit.hxx"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
@ -99,24 +100,21 @@ icy_parse_tag_item(TagBuilder &tag,
|
||||||
* of the string). If that fails, return the first single quote. If
|
* of the string). If that fails, return the first single quote. If
|
||||||
* that also fails, return #end.
|
* that also fails, return #end.
|
||||||
*/
|
*/
|
||||||
static const char *
|
static constexpr std::pair<std::string_view, std::string_view>
|
||||||
find_end_quote(const char *p, const char *const end) noexcept
|
SplitEndQuote(std::string_view s) noexcept
|
||||||
{
|
{
|
||||||
const char *fallback = std::find(p, end, '\'');
|
auto quote = s.find('\'');
|
||||||
if (fallback >= end - 1 || fallback[1] == ';')
|
if (quote == s.npos)
|
||||||
return fallback;
|
return {};
|
||||||
|
|
||||||
p = fallback + 1;
|
if (const auto i = s.find("';"sv, quote); i != s.npos)
|
||||||
while (true) {
|
quote = i;
|
||||||
p = std::find(p, end, '\'');
|
else
|
||||||
if (p == end)
|
quote = s.rfind('\'');
|
||||||
return fallback;
|
|
||||||
|
|
||||||
if (p == end - 1 || p[1] == ';')
|
assert(quote != s.npos);
|
||||||
return p;
|
|
||||||
|
|
||||||
++p;
|
return {s.substr(0, quote), s.substr(quote + 1)};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::unique_ptr<Tag>
|
static std::unique_ptr<Tag>
|
||||||
|
@ -124,52 +122,35 @@ icy_parse_tag(
|
||||||
#ifdef HAVE_ICU_CONVERTER
|
#ifdef HAVE_ICU_CONVERTER
|
||||||
const IcuConverter *icu_converter,
|
const IcuConverter *icu_converter,
|
||||||
#endif
|
#endif
|
||||||
const char *p, const char *const end) noexcept
|
std::string_view src) noexcept
|
||||||
{
|
{
|
||||||
assert(p != nullptr);
|
|
||||||
assert(end != nullptr);
|
|
||||||
assert(p <= end);
|
|
||||||
|
|
||||||
TagBuilder tag;
|
TagBuilder tag;
|
||||||
|
|
||||||
while (p != end) {
|
while (!src.empty()) {
|
||||||
const char *eq = std::find(p, end, '=');
|
const auto [name, rest] = Split(src, '=');
|
||||||
if (eq == end)
|
if (rest.empty())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
const std::string_view name{p, eq};
|
if (rest.front() != '\'') {
|
||||||
|
|
||||||
p = eq + 1;
|
|
||||||
|
|
||||||
if (*p != '\'') {
|
|
||||||
/* syntax error; skip to the next semicolon,
|
/* syntax error; skip to the next semicolon,
|
||||||
try to recover */
|
try to recover */
|
||||||
const char *semicolon = std::find(p, end, ';');
|
src = Split(rest, ';').second;
|
||||||
if (semicolon == end)
|
|
||||||
break;
|
|
||||||
p = semicolon + 1;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
++p;
|
src = rest.substr(1);
|
||||||
|
|
||||||
const char *quote = find_end_quote(p, end);
|
const auto [value, after_value] = SplitEndQuote(rest.substr(1));
|
||||||
if (quote == end)
|
if (after_value.data() == nullptr)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
const std::string_view value{p, quote};
|
|
||||||
p = quote + 1;
|
|
||||||
|
|
||||||
icy_parse_tag_item(tag,
|
icy_parse_tag_item(tag,
|
||||||
#ifdef HAVE_ICU_CONVERTER
|
#ifdef HAVE_ICU_CONVERTER
|
||||||
icu_converter,
|
icu_converter,
|
||||||
#endif
|
#endif
|
||||||
name, value);
|
name, value);
|
||||||
|
|
||||||
const char *semicolon = std::find(p, end, ';');
|
src = Split(after_value, ';').second;
|
||||||
if (semicolon == end)
|
|
||||||
break;
|
|
||||||
p = semicolon + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return tag.CommitNew();
|
return tag.CommitNew();
|
||||||
|
@ -223,7 +204,7 @@ IcyMetaDataParser::Meta(const void *data, size_t length) noexcept
|
||||||
#ifdef HAVE_ICU_CONVERTER
|
#ifdef HAVE_ICU_CONVERTER
|
||||||
icu_converter.get(),
|
icu_converter.get(),
|
||||||
#endif
|
#endif
|
||||||
meta_data, meta_data + meta_size);
|
{meta_data, meta_size});
|
||||||
delete[] meta_data;
|
delete[] meta_data;
|
||||||
|
|
||||||
/* change back to normal data mode */
|
/* change back to normal data mode */
|
||||||
|
|
|
@ -11,16 +11,16 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static std::unique_ptr<Tag>
|
|
||||||
icy_parse_tag(const char *p)
|
|
||||||
{
|
|
||||||
return icy_parse_tag(
|
|
||||||
#ifdef HAVE_ICU_CONVERTER
|
#ifdef HAVE_ICU_CONVERTER
|
||||||
nullptr,
|
|
||||||
#endif
|
static std::unique_ptr<Tag>
|
||||||
p, p + strlen(p));
|
icy_parse_tag(std::string_view p) noexcept
|
||||||
|
{
|
||||||
|
return icy_parse_tag(nullptr, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
CompareTagTitle(const Tag &tag, const std::string &title)
|
CompareTagTitle(const Tag &tag, const std::string &title)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue