playlist/SoundCloud: use AllocatedString for concatenation

This commit is contained in:
Max Kellermann 2021-10-13 12:20:09 +02:00
parent d2b8852d19
commit bf656af555

View File

@ -26,11 +26,10 @@
#include "config/Block.hxx" #include "config/Block.hxx"
#include "input/InputStream.hxx" #include "input/InputStream.hxx"
#include "tag/Builder.hxx" #include "tag/Builder.hxx"
#include "util/AllocatedString.hxx"
#include "util/ASCII.hxx" #include "util/ASCII.hxx"
#include "util/StringCompare.hxx" #include "util/StringCompare.hxx"
#include "util/Alloc.hxx"
#include "util/Domain.hxx" #include "util/Domain.hxx"
#include "util/ScopeExit.hxx"
#include "Log.hxx" #include "Log.hxx"
#include <string> #include <string>
@ -38,6 +37,8 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
using std::string_view_literals::operator""sv;
static struct { static struct {
std::string apikey; std::string apikey;
} soundcloud_config; } soundcloud_config;
@ -64,56 +65,57 @@ soundcloud_init(const ConfigBlock &block)
* @param uri uri of a soundcloud page (or just the path) * @param uri uri of a soundcloud page (or just the path)
* @return Constructed URL. Must be freed with free(). * @return Constructed URL. Must be freed with free().
*/ */
static char * static AllocatedString
soundcloud_resolve(const char* uri) soundcloud_resolve(StringView uri) noexcept
{ {
char *u, *ru; if (uri.StartsWithIgnoreCase("https://")) {
return AllocatedString{uri};
if (StringStartsWithCaseASCII(uri, "https://")) { } else if (uri.StartsWith("soundcloud.com")) {
u = xstrdup(uri); return AllocatedString{"https://"sv, uri};
} else if (StringStartsWith(uri, "soundcloud.com")) {
u = xstrcatdup("https://", uri);
} else {
/* assume it's just a path on soundcloud.com */
u = xstrcatdup("https://soundcloud.com/", uri);
} }
ru = xstrcatdup("https://api.soundcloud.com/resolve.json?url=",
u, "&client_id=",
soundcloud_config.apikey.c_str());
free(u);
return ru; /* assume it's just a path on soundcloud.com */
AllocatedString u{"https://soundcloud.com/"sv, uri};
return AllocatedString{
"https://api.soundcloud.com/resolve.json?url="sv,
u, "&client_id="sv,
soundcloud_config.apikey,
};
} }
static char * static AllocatedString
TranslateSoundCloudUri(const char *uri) noexcept TranslateSoundCloudUri(StringView uri) noexcept
{ {
if (strncmp(uri, "track/", 6) == 0) { if (uri.SkipPrefix("track/"sv)) {
const char *rest = uri + 6; return AllocatedString{
return xstrcatdup("https://api.soundcloud.com/tracks/", "https://api.soundcloud.com/tracks/"sv,
rest, ".json?client_id=", uri, ".json?client_id="sv,
soundcloud_config.apikey.c_str()); soundcloud_config.apikey,
} else if (strncmp(uri, "playlist/", 9) == 0) { };
const char *rest = uri + 9; } else if (uri.SkipPrefix("playlist/"sv)) {
return xstrcatdup("https://api.soundcloud.com/playlists/", return AllocatedString{
rest, ".json?client_id=", "https://api.soundcloud.com/playlists/"sv,
soundcloud_config.apikey.c_str()); uri, ".json?client_id="sv,
} else if (strncmp(uri, "user/", 5) == 0) { soundcloud_config.apikey,
const char *rest = uri + 5; };
return xstrcatdup("https://api.soundcloud.com/users/", } else if (uri.SkipPrefix("user/"sv)) {
rest, "/tracks.json?client_id=", return AllocatedString{
soundcloud_config.apikey.c_str()); "https://api.soundcloud.com/users/"sv,
} else if (strncmp(uri, "search/", 7) == 0) { uri, "/tracks.json?client_id="sv,
const char *rest = uri + 7; soundcloud_config.apikey,
return xstrcatdup("https://api.soundcloud.com/tracks.json?q=", };
rest, "&client_id=", } else if (uri.SkipPrefix("search/"sv)) {
soundcloud_config.apikey.c_str()); return AllocatedString{
} else if (strncmp(uri, "url/", 4) == 0) { "https://api.soundcloud.com/tracks.json?q="sv,
const char *rest = uri + 4; uri, "&client_id="sv,
soundcloud_config.apikey,
};
} else if (uri.SkipPrefix("url/"sv)) {
/* Translate to soundcloud resolver call. libcurl will automatically /* Translate to soundcloud resolver call. libcurl will automatically
follow the redirect to the right resource. */ follow the redirect to the right resource. */
return soundcloud_resolve(rest); return soundcloud_resolve(uri);
} else } else
return nullptr; return nullptr;
} }
@ -272,9 +274,7 @@ soundcloud_open_uri(const char *uri, Mutex &mutex)
assert(StringEqualsCaseASCII(uri, "soundcloud://", 13)); assert(StringEqualsCaseASCII(uri, "soundcloud://", 13));
uri += 13; uri += 13;
char *u = TranslateSoundCloudUri(uri); auto u = TranslateSoundCloudUri(uri);
AtScopeExit(u) { free(u); };
if (u == nullptr) { if (u == nullptr) {
LogWarning(soundcloud_domain, "unknown soundcloud URI"); LogWarning(soundcloud_domain, "unknown soundcloud URI");
return nullptr; return nullptr;
@ -282,7 +282,7 @@ soundcloud_open_uri(const char *uri, Mutex &mutex)
SoundCloudJsonData data; SoundCloudJsonData data;
Yajl::Handle handle(&parse_callbacks, nullptr, &data); Yajl::Handle handle(&parse_callbacks, nullptr, &data);
soundcloud_parse_json(u, handle, mutex); soundcloud_parse_json(u.c_str(), handle, mutex);
data.songs.reverse(); data.songs.reverse();
return std::make_unique<MemorySongEnumerator>(std::move(data.songs)); return std::make_unique<MemorySongEnumerator>(std::move(data.songs));