util/UriExtract: uri_get_suffix() returns std::string_view
No need to copy it to a buffer.
This commit is contained in:
parent
19dd1a25d7
commit
35a232105e
@ -36,10 +36,10 @@
|
|||||||
gcc_pure
|
gcc_pure
|
||||||
static bool
|
static bool
|
||||||
CheckDecoderPlugin(const DecoderPlugin &plugin,
|
CheckDecoderPlugin(const DecoderPlugin &plugin,
|
||||||
const char *suffix, const char *mime) noexcept
|
std::string_view suffix, const char *mime) noexcept
|
||||||
{
|
{
|
||||||
return (mime != nullptr && plugin.SupportsMimeType(mime)) ||
|
return (mime != nullptr && plugin.SupportsMimeType(mime)) ||
|
||||||
(suffix != nullptr && plugin.SupportsSuffix(suffix));
|
(!suffix.empty() && plugin.SupportsSuffix(suffix));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -47,11 +47,10 @@ tag_stream_scan(InputStream &is, TagHandler &handler)
|
|||||||
{
|
{
|
||||||
assert(is.IsReady());
|
assert(is.IsReady());
|
||||||
|
|
||||||
UriSuffixBuffer suffix_buffer;
|
const auto suffix = uri_get_suffix(is.GetURI());
|
||||||
const char *const suffix = uri_get_suffix(is.GetURI(), suffix_buffer);
|
|
||||||
const char *mime = is.GetMimeType();
|
const char *mime = is.GetMimeType();
|
||||||
|
|
||||||
if (suffix == nullptr && mime == nullptr)
|
if (suffix.empty() && mime == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::string mime_base;
|
std::string mime_base;
|
||||||
|
@ -72,12 +72,12 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void DecodeStream(InputStream &is, const DecoderPlugin &plugin);
|
void DecodeStream(InputStream &is, const DecoderPlugin &plugin);
|
||||||
bool DecodeStream(InputStream &is, const char *suffix,
|
bool DecodeStream(InputStream &is, std::string_view suffix,
|
||||||
const DecoderPlugin &plugin);
|
const DecoderPlugin &plugin);
|
||||||
void DecodeStream(InputStream &is);
|
void DecodeStream(InputStream &is);
|
||||||
bool DecodeContainer(const char *suffix, const DecoderPlugin &plugin);
|
bool DecodeContainer(std::string_view suffix, const DecoderPlugin &plugin);
|
||||||
bool DecodeContainer(const char *suffix);
|
bool DecodeContainer(std::string_view suffix);
|
||||||
bool DecodeFile(const char *suffix, InputStream &is,
|
bool DecodeFile(std::string_view suffix, InputStream &is,
|
||||||
const DecoderPlugin &plugin);
|
const DecoderPlugin &plugin);
|
||||||
void DecodeFile();
|
void DecodeFile();
|
||||||
|
|
||||||
@ -130,17 +130,17 @@ decoder_check_plugin_mime(const DecoderPlugin &plugin,
|
|||||||
gcc_pure
|
gcc_pure
|
||||||
static bool
|
static bool
|
||||||
decoder_check_plugin_suffix(const DecoderPlugin &plugin,
|
decoder_check_plugin_suffix(const DecoderPlugin &plugin,
|
||||||
const char *suffix) noexcept
|
std::string_view suffix) noexcept
|
||||||
{
|
{
|
||||||
assert(plugin.stream_decode != nullptr);
|
assert(plugin.stream_decode != nullptr);
|
||||||
|
|
||||||
return suffix != nullptr && plugin.SupportsSuffix(suffix);
|
return !suffix.empty() && plugin.SupportsSuffix(suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
gcc_pure
|
gcc_pure
|
||||||
static bool
|
static bool
|
||||||
decoder_check_plugin(const DecoderPlugin &plugin, const InputStream &is,
|
decoder_check_plugin(const DecoderPlugin &plugin, const InputStream &is,
|
||||||
const char *suffix) noexcept
|
std::string_view suffix) noexcept
|
||||||
{
|
{
|
||||||
return plugin.stream_decode != nullptr &&
|
return plugin.stream_decode != nullptr &&
|
||||||
(decoder_check_plugin_mime(plugin, is) ||
|
(decoder_check_plugin_mime(plugin, is) ||
|
||||||
@ -149,7 +149,7 @@ decoder_check_plugin(const DecoderPlugin &plugin, const InputStream &is,
|
|||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
GetChromaprintCommand::DecodeStream(InputStream &is,
|
GetChromaprintCommand::DecodeStream(InputStream &is,
|
||||||
const char *suffix,
|
std::string_view suffix,
|
||||||
const DecoderPlugin &plugin)
|
const DecoderPlugin &plugin)
|
||||||
{
|
{
|
||||||
if (!decoder_check_plugin(plugin, is, suffix))
|
if (!decoder_check_plugin(plugin, is, suffix))
|
||||||
@ -164,8 +164,7 @@ GetChromaprintCommand::DecodeStream(InputStream &is,
|
|||||||
inline void
|
inline void
|
||||||
GetChromaprintCommand::DecodeStream(InputStream &is)
|
GetChromaprintCommand::DecodeStream(InputStream &is)
|
||||||
{
|
{
|
||||||
UriSuffixBuffer suffix_buffer;
|
const auto suffix = uri_get_suffix(uri.c_str());
|
||||||
const char *const suffix = uri_get_suffix(uri.c_str(), suffix_buffer);
|
|
||||||
|
|
||||||
decoder_plugins_try([this, &is, suffix](const DecoderPlugin &plugin){
|
decoder_plugins_try([this, &is, suffix](const DecoderPlugin &plugin){
|
||||||
return DecodeStream(is, suffix, plugin);
|
return DecodeStream(is, suffix, plugin);
|
||||||
@ -173,7 +172,7 @@ GetChromaprintCommand::DecodeStream(InputStream &is)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
GetChromaprintCommand::DecodeContainer(const char *suffix,
|
GetChromaprintCommand::DecodeContainer(std::string_view suffix,
|
||||||
const DecoderPlugin &plugin)
|
const DecoderPlugin &plugin)
|
||||||
{
|
{
|
||||||
if (plugin.container_scan == nullptr ||
|
if (plugin.container_scan == nullptr ||
|
||||||
@ -188,7 +187,7 @@ GetChromaprintCommand::DecodeContainer(const char *suffix,
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
GetChromaprintCommand::DecodeContainer(const char *suffix)
|
GetChromaprintCommand::DecodeContainer(std::string_view suffix)
|
||||||
{
|
{
|
||||||
return decoder_plugins_try([this, suffix](const DecoderPlugin &plugin){
|
return decoder_plugins_try([this, suffix](const DecoderPlugin &plugin){
|
||||||
return DecodeContainer(suffix, plugin);
|
return DecodeContainer(suffix, plugin);
|
||||||
@ -196,7 +195,7 @@ GetChromaprintCommand::DecodeContainer(const char *suffix)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
GetChromaprintCommand::DecodeFile(const char *suffix, InputStream &is,
|
GetChromaprintCommand::DecodeFile(std::string_view suffix, InputStream &is,
|
||||||
const DecoderPlugin &plugin)
|
const DecoderPlugin &plugin)
|
||||||
{
|
{
|
||||||
if (!plugin.SupportsSuffix(suffix))
|
if (!plugin.SupportsSuffix(suffix))
|
||||||
@ -223,8 +222,8 @@ GetChromaprintCommand::DecodeFile(const char *suffix, InputStream &is,
|
|||||||
inline void
|
inline void
|
||||||
GetChromaprintCommand::DecodeFile()
|
GetChromaprintCommand::DecodeFile()
|
||||||
{
|
{
|
||||||
const char *suffix = uri_get_suffix(uri.c_str());
|
const auto suffix = uri_get_suffix(uri.c_str());
|
||||||
if (suffix == nullptr)
|
if (suffix.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
InputStreamPtr input_stream;
|
InputStreamPtr input_stream;
|
||||||
|
@ -157,7 +157,7 @@ UpdateWalk::UpdateArchiveFile(Directory &parent, std::string_view name,
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
UpdateWalk::UpdateArchiveFile(Directory &directory,
|
UpdateWalk::UpdateArchiveFile(Directory &directory,
|
||||||
std::string_view name, const char *suffix,
|
std::string_view name, std::string_view suffix,
|
||||||
const StorageFileInfo &info) noexcept
|
const StorageFileInfo &info) noexcept
|
||||||
{
|
{
|
||||||
const ArchivePlugin *plugin = archive_plugin_from_suffix(suffix);
|
const ArchivePlugin *plugin = archive_plugin_from_suffix(suffix);
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
UpdateWalk::UpdateContainerFile(Directory &directory,
|
UpdateWalk::UpdateContainerFile(Directory &directory,
|
||||||
std::string_view name, const char *suffix,
|
std::string_view name, std::string_view suffix,
|
||||||
const StorageFileInfo &info) noexcept
|
const StorageFileInfo &info) noexcept
|
||||||
{
|
{
|
||||||
const DecoderPlugin *_plugin = decoder_plugins_find([suffix](const DecoderPlugin &plugin){
|
const DecoderPlugin *_plugin = decoder_plugins_find([suffix](const DecoderPlugin &plugin){
|
||||||
|
@ -88,7 +88,7 @@ UpdateWalk::UpdatePlaylistFile(Directory &parent, std::string_view name,
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
UpdateWalk::UpdatePlaylistFile(Directory &directory,
|
UpdateWalk::UpdatePlaylistFile(Directory &directory,
|
||||||
std::string_view name, const char *suffix,
|
std::string_view name, std::string_view suffix,
|
||||||
const StorageFileInfo &info) noexcept
|
const StorageFileInfo &info) noexcept
|
||||||
{
|
{
|
||||||
const auto *const plugin = FindPlaylistPluginBySuffix(suffix);
|
const auto *const plugin = FindPlaylistPluginBySuffix(suffix);
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
inline void
|
inline void
|
||||||
UpdateWalk::UpdateSongFile2(Directory &directory,
|
UpdateWalk::UpdateSongFile2(Directory &directory,
|
||||||
const char *name, const char *suffix,
|
const char *name, std::string_view suffix,
|
||||||
const StorageFileInfo &info) noexcept
|
const StorageFileInfo &info) noexcept
|
||||||
try {
|
try {
|
||||||
Song *song;
|
Song *song;
|
||||||
@ -98,7 +98,7 @@ try {
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
UpdateWalk::UpdateSongFile(Directory &directory,
|
UpdateWalk::UpdateSongFile(Directory &directory,
|
||||||
const char *name, const char *suffix,
|
const char *name, std::string_view suffix,
|
||||||
const StorageFileInfo &info) noexcept
|
const StorageFileInfo &info) noexcept
|
||||||
{
|
{
|
||||||
if (!decoder_plugins_supports_suffix(suffix))
|
if (!decoder_plugins_supports_suffix(suffix))
|
||||||
|
@ -189,8 +189,8 @@ UpdateWalk::UpdateRegularFile(Directory &directory,
|
|||||||
const char *name,
|
const char *name,
|
||||||
const StorageFileInfo &info) noexcept
|
const StorageFileInfo &info) noexcept
|
||||||
{
|
{
|
||||||
const char *suffix = uri_get_suffix(name);
|
const auto suffix = uri_get_suffix(name);
|
||||||
if (suffix == nullptr)
|
if (suffix.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return UpdateSongFile(directory, name, suffix, info) ||
|
return UpdateSongFile(directory, name, suffix, info) ||
|
||||||
|
@ -86,15 +86,15 @@ private:
|
|||||||
void PurgeDeletedFromDirectory(Directory &directory) noexcept;
|
void PurgeDeletedFromDirectory(Directory &directory) noexcept;
|
||||||
|
|
||||||
void UpdateSongFile2(Directory &directory,
|
void UpdateSongFile2(Directory &directory,
|
||||||
const char *name, const char *suffix,
|
const char *name, std::string_view suffix,
|
||||||
const StorageFileInfo &info) noexcept;
|
const StorageFileInfo &info) noexcept;
|
||||||
|
|
||||||
bool UpdateSongFile(Directory &directory,
|
bool UpdateSongFile(Directory &directory,
|
||||||
const char *name, const char *suffix,
|
const char *name, std::string_view suffix,
|
||||||
const StorageFileInfo &info) noexcept;
|
const StorageFileInfo &info) noexcept;
|
||||||
|
|
||||||
bool UpdateContainerFile(Directory &directory,
|
bool UpdateContainerFile(Directory &directory,
|
||||||
std::string_view name, const char *suffix,
|
std::string_view name, std::string_view suffix,
|
||||||
const StorageFileInfo &info) noexcept;
|
const StorageFileInfo &info) noexcept;
|
||||||
|
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ private:
|
|||||||
const char *name) noexcept;
|
const char *name) noexcept;
|
||||||
|
|
||||||
bool UpdateArchiveFile(Directory &directory,
|
bool UpdateArchiveFile(Directory &directory,
|
||||||
std::string_view name, const char *suffix,
|
std::string_view name, std::string_view suffix,
|
||||||
const StorageFileInfo &info) noexcept;
|
const StorageFileInfo &info) noexcept;
|
||||||
|
|
||||||
void UpdateArchiveFile(Directory &directory, std::string_view name,
|
void UpdateArchiveFile(Directory &directory, std::string_view name,
|
||||||
@ -114,7 +114,7 @@ private:
|
|||||||
#else
|
#else
|
||||||
bool UpdateArchiveFile([[maybe_unused]] Directory &directory,
|
bool UpdateArchiveFile([[maybe_unused]] Directory &directory,
|
||||||
[[maybe_unused]] const char *name,
|
[[maybe_unused]] const char *name,
|
||||||
[[maybe_unused]] const char *suffix,
|
[[maybe_unused]] std::string_view suffix,
|
||||||
[[maybe_unused]] const StorageFileInfo &info) noexcept {
|
[[maybe_unused]] const StorageFileInfo &info) noexcept {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -125,7 +125,7 @@ private:
|
|||||||
const PlaylistPlugin &plugin) noexcept;
|
const PlaylistPlugin &plugin) noexcept;
|
||||||
|
|
||||||
bool UpdatePlaylistFile(Directory &directory,
|
bool UpdatePlaylistFile(Directory &directory,
|
||||||
std::string_view name, const char *suffix,
|
std::string_view name, std::string_view suffix,
|
||||||
const StorageFileInfo &info) noexcept;
|
const StorageFileInfo &info) noexcept;
|
||||||
|
|
||||||
bool UpdateRegularFile(Directory &directory,
|
bool UpdateRegularFile(Directory &directory,
|
||||||
|
@ -178,17 +178,17 @@ decoder_check_plugin_mime(const DecoderPlugin &plugin,
|
|||||||
gcc_pure
|
gcc_pure
|
||||||
static bool
|
static bool
|
||||||
decoder_check_plugin_suffix(const DecoderPlugin &plugin,
|
decoder_check_plugin_suffix(const DecoderPlugin &plugin,
|
||||||
const char *suffix) noexcept
|
std::string_view suffix) noexcept
|
||||||
{
|
{
|
||||||
assert(plugin.stream_decode != nullptr);
|
assert(plugin.stream_decode != nullptr);
|
||||||
|
|
||||||
return suffix != nullptr && plugin.SupportsSuffix(suffix);
|
return !suffix.empty() && plugin.SupportsSuffix(suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
gcc_pure
|
gcc_pure
|
||||||
static bool
|
static bool
|
||||||
decoder_check_plugin(const DecoderPlugin &plugin, const InputStream &is,
|
decoder_check_plugin(const DecoderPlugin &plugin, const InputStream &is,
|
||||||
const char *suffix) noexcept
|
std::string_view suffix) noexcept
|
||||||
{
|
{
|
||||||
return plugin.stream_decode != nullptr &&
|
return plugin.stream_decode != nullptr &&
|
||||||
(decoder_check_plugin_mime(plugin, is) ||
|
(decoder_check_plugin_mime(plugin, is) ||
|
||||||
@ -198,7 +198,7 @@ decoder_check_plugin(const DecoderPlugin &plugin, const InputStream &is,
|
|||||||
static bool
|
static bool
|
||||||
decoder_run_stream_plugin(DecoderBridge &bridge, InputStream &is,
|
decoder_run_stream_plugin(DecoderBridge &bridge, InputStream &is,
|
||||||
std::unique_lock<Mutex> &lock,
|
std::unique_lock<Mutex> &lock,
|
||||||
const char *suffix,
|
std::string_view suffix,
|
||||||
const DecoderPlugin &plugin,
|
const DecoderPlugin &plugin,
|
||||||
bool &tried_r)
|
bool &tried_r)
|
||||||
{
|
{
|
||||||
@ -216,8 +216,7 @@ decoder_run_stream_locked(DecoderBridge &bridge, InputStream &is,
|
|||||||
std::unique_lock<Mutex> &lock,
|
std::unique_lock<Mutex> &lock,
|
||||||
const char *uri, bool &tried_r)
|
const char *uri, bool &tried_r)
|
||||||
{
|
{
|
||||||
UriSuffixBuffer suffix_buffer;
|
const auto suffix = uri_get_suffix(uri);
|
||||||
const char *const suffix = uri_get_suffix(uri, suffix_buffer);
|
|
||||||
|
|
||||||
const auto f = [&,suffix](const auto &plugin)
|
const auto f = [&,suffix](const auto &plugin)
|
||||||
{ return decoder_run_stream_plugin(bridge, is, lock, suffix, plugin, tried_r); };
|
{ return decoder_run_stream_plugin(bridge, is, lock, suffix, plugin, tried_r); };
|
||||||
@ -326,7 +325,7 @@ decoder_run_stream(DecoderBridge &bridge, const char *uri)
|
|||||||
* DecoderControl::mutex is not locked by caller.
|
* DecoderControl::mutex is not locked by caller.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
TryDecoderFile(DecoderBridge &bridge, Path path_fs, const char *suffix,
|
TryDecoderFile(DecoderBridge &bridge, Path path_fs, std::string_view suffix,
|
||||||
InputStream &input_stream,
|
InputStream &input_stream,
|
||||||
const DecoderPlugin &plugin)
|
const DecoderPlugin &plugin)
|
||||||
{
|
{
|
||||||
@ -354,7 +353,8 @@ TryDecoderFile(DecoderBridge &bridge, Path path_fs, const char *suffix,
|
|||||||
* DecoderControl::mutex is not locked by caller.
|
* DecoderControl::mutex is not locked by caller.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
TryContainerDecoder(DecoderBridge &bridge, Path path_fs, const char *suffix,
|
TryContainerDecoder(DecoderBridge &bridge, Path path_fs,
|
||||||
|
std::string_view suffix,
|
||||||
const DecoderPlugin &plugin)
|
const DecoderPlugin &plugin)
|
||||||
{
|
{
|
||||||
if (plugin.container_scan == nullptr ||
|
if (plugin.container_scan == nullptr ||
|
||||||
@ -375,7 +375,8 @@ TryContainerDecoder(DecoderBridge &bridge, Path path_fs, const char *suffix,
|
|||||||
* DecoderControl::mutex is not locked by caller.
|
* DecoderControl::mutex is not locked by caller.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
TryContainerDecoder(DecoderBridge &bridge, Path path_fs, const char *suffix)
|
TryContainerDecoder(DecoderBridge &bridge, Path path_fs,
|
||||||
|
std::string_view suffix)
|
||||||
{
|
{
|
||||||
return decoder_plugins_try([&bridge, path_fs,
|
return decoder_plugins_try([&bridge, path_fs,
|
||||||
suffix](const DecoderPlugin &plugin){
|
suffix](const DecoderPlugin &plugin){
|
||||||
@ -394,8 +395,8 @@ TryContainerDecoder(DecoderBridge &bridge, Path path_fs, const char *suffix)
|
|||||||
static bool
|
static bool
|
||||||
decoder_run_file(DecoderBridge &bridge, const char *uri_utf8, Path path_fs)
|
decoder_run_file(DecoderBridge &bridge, const char *uri_utf8, Path path_fs)
|
||||||
{
|
{
|
||||||
const char *suffix = uri_get_suffix(uri_utf8);
|
const auto suffix = uri_get_suffix(uri_utf8);
|
||||||
if (suffix == nullptr)
|
if (suffix.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
InputStreamPtr input_stream;
|
InputStreamPtr input_stream;
|
||||||
|
@ -157,9 +157,8 @@ playlist_list_open_uri_suffix(const char *uri, Mutex &mutex,
|
|||||||
{
|
{
|
||||||
assert(uri != nullptr);
|
assert(uri != nullptr);
|
||||||
|
|
||||||
UriSuffixBuffer suffix_buffer;
|
const auto suffix = uri_get_suffix(uri);
|
||||||
const char *const suffix = uri_get_suffix(uri, suffix_buffer);
|
if (suffix.empty())
|
||||||
if (suffix == nullptr)
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
for (unsigned i = 0; playlist_plugins[i] != nullptr; ++i) {
|
for (unsigned i = 0; playlist_plugins[i] != nullptr; ++i) {
|
||||||
@ -272,15 +271,14 @@ playlist_list_open_stream(InputStreamPtr &&is, const char *uri)
|
|||||||
return playlist;
|
return playlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
UriSuffixBuffer suffix_buffer;
|
if (uri != nullptr) {
|
||||||
const char *suffix = uri != nullptr
|
const auto suffix = uri_get_suffix(uri);
|
||||||
? uri_get_suffix(uri, suffix_buffer)
|
if (!suffix.empty()) {
|
||||||
: nullptr;
|
auto playlist = playlist_list_open_stream_suffix(std::move(is),
|
||||||
if (suffix != nullptr) {
|
suffix);
|
||||||
auto playlist = playlist_list_open_stream_suffix(std::move(is),
|
if (playlist != nullptr)
|
||||||
suffix);
|
return playlist;
|
||||||
if (playlist != nullptr)
|
}
|
||||||
return playlist;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -121,37 +121,21 @@ uri_get_path(std::string_view uri) noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* suffixes should be ascii only characters */
|
/* suffixes should be ascii only characters */
|
||||||
const char *
|
std::string_view
|
||||||
uri_get_suffix(const char *uri) noexcept
|
uri_get_suffix(const char *uri) noexcept
|
||||||
{
|
{
|
||||||
const char *suffix = std::strrchr(uri, '.');
|
const char *suffix = std::strrchr(uri, '.');
|
||||||
if (suffix == nullptr || suffix == uri ||
|
if (suffix == nullptr || suffix == uri ||
|
||||||
suffix[-1] == '/' || suffix[-1] == '\\')
|
suffix[-1] == '/' || suffix[-1] == '\\')
|
||||||
return nullptr;
|
return {};
|
||||||
|
|
||||||
++suffix;
|
++suffix;
|
||||||
|
|
||||||
if (strpbrk(suffix, "/\\") != nullptr)
|
if (strpbrk(suffix, "/\\") != nullptr)
|
||||||
return nullptr;
|
return {};
|
||||||
|
|
||||||
return suffix;
|
/* remove the query string */
|
||||||
}
|
return StringView(suffix).Split('?').first;
|
||||||
|
|
||||||
const char *
|
|
||||||
uri_get_suffix(const char *uri, UriSuffixBuffer &buffer) noexcept
|
|
||||||
{
|
|
||||||
const char *suffix = uri_get_suffix(uri);
|
|
||||||
if (suffix == nullptr)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
const char *q = std::strchr(suffix, '?');
|
|
||||||
if (q != nullptr && size_t(q - suffix) < sizeof(buffer.data)) {
|
|
||||||
memcpy(buffer.data, suffix, q - suffix);
|
|
||||||
buffer.data[q - suffix] = 0;
|
|
||||||
suffix = buffer.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
return suffix;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
@ -62,20 +62,9 @@ std::string_view
|
|||||||
uri_get_path(std::string_view uri) noexcept;
|
uri_get_path(std::string_view uri) noexcept;
|
||||||
|
|
||||||
gcc_pure
|
gcc_pure
|
||||||
const char *
|
std::string_view
|
||||||
uri_get_suffix(const char *uri) noexcept;
|
uri_get_suffix(const char *uri) noexcept;
|
||||||
|
|
||||||
struct UriSuffixBuffer {
|
|
||||||
char data[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the file name suffix, ignoring the query string.
|
|
||||||
*/
|
|
||||||
gcc_pure
|
|
||||||
const char *
|
|
||||||
uri_get_suffix(const char *uri, UriSuffixBuffer &buffer) noexcept;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the URI fragment, i.e. the portion after the '#', but
|
* Returns the URI fragment, i.e. the portion after the '#', but
|
||||||
* without the '#'. If there is no '#', this function returns
|
* without the '#'. If there is no '#', this function returns
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
static const DecoderPlugin *
|
static const DecoderPlugin *
|
||||||
FindContainerDecoderPlugin(const char *suffix)
|
FindContainerDecoderPlugin(std::string_view suffix)
|
||||||
{
|
{
|
||||||
return decoder_plugins_find([suffix](const DecoderPlugin &plugin){
|
return decoder_plugins_find([suffix](const DecoderPlugin &plugin){
|
||||||
return plugin.container_scan != nullptr &&
|
return plugin.container_scan != nullptr &&
|
||||||
@ -48,10 +48,8 @@ FindContainerDecoderPlugin(const char *suffix)
|
|||||||
static const DecoderPlugin *
|
static const DecoderPlugin *
|
||||||
FindContainerDecoderPlugin(Path path)
|
FindContainerDecoderPlugin(Path path)
|
||||||
{
|
{
|
||||||
UriSuffixBuffer suffix_buffer;
|
const auto suffix = uri_get_suffix(path.ToUTF8Throw().c_str());
|
||||||
const char *const suffix = uri_get_suffix(path.ToUTF8Throw().c_str(),
|
if (suffix.empty())
|
||||||
suffix_buffer);
|
|
||||||
if (suffix == nullptr)
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return FindContainerDecoderPlugin(suffix);
|
return FindContainerDecoderPlugin(suffix);
|
||||||
|
@ -6,28 +6,17 @@
|
|||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
using std::string_view_literals::operator""sv;
|
||||||
|
|
||||||
TEST(UriExtract, Suffix)
|
TEST(UriExtract, Suffix)
|
||||||
{
|
{
|
||||||
EXPECT_EQ((const char *)nullptr, uri_get_suffix("/foo/bar"));
|
EXPECT_EQ((const char *)nullptr, uri_get_suffix("/foo/bar").data());
|
||||||
EXPECT_EQ((const char *)nullptr, uri_get_suffix("/foo.jpg/bar"));
|
EXPECT_EQ((const char *)nullptr, uri_get_suffix("/foo.jpg/bar").data());
|
||||||
EXPECT_STREQ(uri_get_suffix("/foo/bar.jpg"), "jpg");
|
EXPECT_EQ(uri_get_suffix("/foo/bar.jpg"), "jpg"sv);
|
||||||
EXPECT_STREQ(uri_get_suffix("/foo.png/bar.jpg"), "jpg");
|
EXPECT_EQ(uri_get_suffix("/foo.png/bar.jpg"), "jpg"sv);
|
||||||
EXPECT_EQ((const char *)nullptr, uri_get_suffix(".jpg"));
|
EXPECT_EQ((const char *)nullptr, uri_get_suffix(".jpg").data());
|
||||||
EXPECT_EQ((const char *)nullptr, uri_get_suffix("/foo/.jpg"));
|
EXPECT_EQ((const char *)nullptr, uri_get_suffix("/foo/.jpg").data());
|
||||||
|
|
||||||
/* the first overload does not eliminate the query
|
/* eliminate the query string */
|
||||||
string */
|
EXPECT_EQ(uri_get_suffix("/foo/bar.jpg?query_string"), "jpg"sv);
|
||||||
EXPECT_STREQ(uri_get_suffix("/foo/bar.jpg?query_string"),
|
|
||||||
"jpg?query_string");
|
|
||||||
|
|
||||||
/* ... but the second one does */
|
|
||||||
UriSuffixBuffer buffer;
|
|
||||||
EXPECT_STREQ(uri_get_suffix("/foo/bar.jpg?query_string", buffer),
|
|
||||||
"jpg");
|
|
||||||
|
|
||||||
/* repeat some of the above tests with the second overload */
|
|
||||||
EXPECT_EQ((const char *)nullptr, uri_get_suffix("/foo/bar", buffer));
|
|
||||||
EXPECT_EQ((const char *)nullptr,
|
|
||||||
uri_get_suffix("/foo.jpg/bar", buffer));
|
|
||||||
EXPECT_STREQ(uri_get_suffix("/foo/bar.jpg", buffer), "jpg");
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user