IcyMetadataParser: implement charset conversion

This commit is contained in:
Max Kellermann 2019-08-09 15:03:07 +02:00
parent 7654038d65
commit 4a47bbd816
4 changed files with 62 additions and 5 deletions

View File

@ -19,6 +19,7 @@
#include "IcyMetaDataParser.hxx" #include "IcyMetaDataParser.hxx"
#include "tag/Builder.hxx" #include "tag/Builder.hxx"
#include "util/AllocatedString.hxx"
#include "util/StringView.hxx" #include "util/StringView.hxx"
#include <algorithm> #include <algorithm>
@ -26,6 +27,16 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#ifdef HAVE_ICU_CONVERTER
void
IcyMetaDataParser::SetCharset(const char *charset)
{
icu_converter.reset(IcuConverter::Create(charset));
}
#endif
void void
IcyMetaDataParser::Reset() noexcept IcyMetaDataParser::Reset() noexcept
{ {
@ -76,10 +87,26 @@ icy_add_item(TagBuilder &tag, TagType type, StringView value) noexcept
static void static void
icy_parse_tag_item(TagBuilder &tag, icy_parse_tag_item(TagBuilder &tag,
#ifdef HAVE_ICU_CONVERTER
const IcuConverter *icu_converter,
#endif
const char *name, const char *value) noexcept const char *name, const char *value) noexcept
{ {
if (strcmp(name, "StreamTitle") == 0) if (strcmp(name, "StreamTitle") == 0) {
#ifdef HAVE_ICU_CONVERTER
if (icu_converter != nullptr) {
try {
icy_add_item(tag, TAG_TITLE,
icu_converter->ToUTF8(value).c_str());
} catch (...) {
}
return;
}
#endif
icy_add_item(tag, TAG_TITLE, value); icy_add_item(tag, TAG_TITLE, value);
}
} }
/** /**
@ -108,7 +135,11 @@ find_end_quote(char *p, char *const end) noexcept
} }
static std::unique_ptr<Tag> static std::unique_ptr<Tag>
icy_parse_tag(char *p, char *const end) noexcept icy_parse_tag(
#ifdef HAVE_ICU_CONVERTER
const IcuConverter *icu_converter,
#endif
char *p, char *const end) noexcept
{ {
assert(p != nullptr); assert(p != nullptr);
assert(end != nullptr); assert(end != nullptr);
@ -145,7 +176,11 @@ icy_parse_tag(char *p, char *const end) noexcept
*quote = 0; *quote = 0;
p = quote + 1; p = quote + 1;
icy_parse_tag_item(tag, name, value); icy_parse_tag_item(tag,
#ifdef HAVE_ICU_CONVERTER
icu_converter,
#endif
name, value);
char *semicolon = std::find(p, end, ';'); char *semicolon = std::find(p, end, ';');
if (semicolon == end) if (semicolon == end)
@ -200,7 +235,11 @@ IcyMetaDataParser::Meta(const void *data, size_t length) noexcept
if (meta_position == meta_size) { if (meta_position == meta_size) {
/* parse */ /* parse */
tag = icy_parse_tag(meta_data, meta_data + meta_size); tag = icy_parse_tag(
#ifdef HAVE_ICU_CONVERTER
icu_converter.get(),
#endif
meta_data, meta_data + meta_size);
delete[] meta_data; delete[] meta_data;
/* change back to normal data mode */ /* change back to normal data mode */

View File

@ -20,7 +20,9 @@
#ifndef MPD_ICY_META_DATA_PARSER_HXX #ifndef MPD_ICY_META_DATA_PARSER_HXX
#define MPD_ICY_META_DATA_PARSER_HXX #define MPD_ICY_META_DATA_PARSER_HXX
#include "lib/icu/Converter.hxx"
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "config.h"
#include <memory> #include <memory>
@ -32,6 +34,10 @@ class IcyMetaDataParser {
size_t meta_size, meta_position; size_t meta_size, meta_position;
char *meta_data; char *meta_data;
#ifdef HAVE_ICU_CONVERTER
std::unique_ptr<IcuConverter> icu_converter;
#endif
std::unique_ptr<Tag> tag; std::unique_ptr<Tag> tag;
public: public:
@ -39,6 +45,13 @@ public:
Reset(); Reset();
} }
#ifdef HAVE_ICU_CONVERTER
/**
* Throws on error.
*/
void SetCharset(const char *charset);
#endif
/** /**
* Initialize an enabled icy_metadata object with the specified * Initialize an enabled icy_metadata object with the specified
* data_size (from the icy-metaint HTTP response header). * data_size (from the icy-metaint HTTP response header).

View File

@ -335,6 +335,7 @@ if curl_dep.found()
'../src/LogBackend.cxx', '../src/LogBackend.cxx',
include_directories: inc, include_directories: inc,
dependencies: [ dependencies: [
icu_dep,
tag_dep, tag_dep,
gtest_dep, gtest_dep,
], ],

View File

@ -18,7 +18,11 @@ icy_parse_tag(const char *p)
{ {
char *q = strdup(p); char *q = strdup(p);
AtScopeExit(q) { free(q); }; AtScopeExit(q) { free(q); };
return icy_parse_tag(q, q + strlen(q)); return icy_parse_tag(
#ifdef HAVE_ICU_CONVERTER
nullptr,
#endif
q, q + strlen(q));
} }
static void static void