From 5899a272efa5f09fd78173891a307fd335838237 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 2 Dec 2014 07:11:11 +0100 Subject: decoder/gme: simplify ParseContainerPath() Use simple string and path parsing functions instead of GLib's g_pattern_match(), which was used in a very clumsy way. --- src/decoder/plugins/GmeDecoderPlugin.cxx | 59 +++++++++++++++----------------- 1 file changed, 27 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/decoder/plugins/GmeDecoderPlugin.cxx b/src/decoder/plugins/GmeDecoderPlugin.cxx index 09404b097..8d3116ae1 100644 --- a/src/decoder/plugins/GmeDecoderPlugin.cxx +++ b/src/decoder/plugins/GmeDecoderPlugin.cxx @@ -23,6 +23,7 @@ #include "CheckAudioFormat.hxx" #include "tag/TagHandler.hxx" #include "fs/Path.hxx" +#include "fs/AllocatedPath.hxx" #include "util/Alloc.hxx" #include "util/FormatString.hxx" #include "util/UriUtil.hxx" @@ -30,7 +31,6 @@ #include "util/Domain.hxx" #include "Log.hxx" -#include #include #include #include @@ -48,10 +48,27 @@ static constexpr unsigned GME_BUFFER_SAMPLES = GME_BUFFER_FRAMES * GME_CHANNELS; struct GmeContainerPath { - char *path; + AllocatedPath path; unsigned track; }; +gcc_pure +static unsigned +ParseSubtuneName(const char *base) +{ + if (memcmp(base, SUBTUNE_PREFIX, sizeof(SUBTUNE_PREFIX) - 1) != 0) + return 0; + + base += sizeof(SUBTUNE_PREFIX) - 1; + + char *endptr; + auto track = strtoul(base, &endptr, 10); + if (endptr == base || *endptr != '.') + return 0; + + return track; +} + /** * returns the file path stripped of any /tune_xxx.* subtune suffix * and the track number (or 0 if no "tune_xxx" suffix is present). @@ -59,33 +76,13 @@ struct GmeContainerPath { static GmeContainerPath ParseContainerPath(Path path_fs) { - const char *subtune_suffix = uri_get_suffix(path_fs.c_str()); - char *path_container = xstrdup(path_fs.c_str()); - - char pat[64]; - snprintf(pat, sizeof(pat), "%s%s", - "*/" SUBTUNE_PREFIX "???.", - subtune_suffix); - GPatternSpec *path_with_subtune = g_pattern_spec_new(pat); - if (!g_pattern_match(path_with_subtune, - strlen(path_container), path_container, nullptr)) { - g_pattern_spec_free(path_with_subtune); - return { path_container, 0 }; - } - - unsigned track = 0; - - char *sub = g_strrstr(path_container, "/" SUBTUNE_PREFIX); - if (sub != nullptr) { - *sub = '\0'; - sub += strlen("/" SUBTUNE_PREFIX); - int song_num = strtol(sub, nullptr, 10); - if (song_num >= 1) - track = song_num - 1; - } + const Path base = path_fs.GetBase(); + unsigned track; + if (base.IsNull() || + (track = ParseSubtuneName(base.c_str())) < 1) + return { AllocatedPath(path_fs), 0 }; - g_pattern_spec_free(path_with_subtune); - return { path_container, track }; + return { path_fs.GetDirectoryName(), track - 1 }; } static char * @@ -120,8 +117,7 @@ gme_file_decode(Decoder &decoder, Path path_fs) Music_Emu *emu; const char *gme_err = - gme_open_file(container.path, &emu, GME_SAMPLE_RATE); - free(container.path); + gme_open_file(container.path.c_str(), &emu, GME_SAMPLE_RATE); if (gme_err != nullptr) { LogWarning(gme_domain, gme_err); return; @@ -256,8 +252,7 @@ gme_scan_file(Path path_fs, Music_Emu *emu; const char *gme_err = - gme_open_file(container.path, &emu, GME_SAMPLE_RATE); - free(container.path); + gme_open_file(container.path.c_str(), &emu, GME_SAMPLE_RATE); if (gme_err != nullptr) { LogWarning(gme_domain, gme_err); return false; -- cgit v1.2.3