GetBaseUTF8

This commit is contained in:
Max Kellermann 2013-10-21 10:26:53 +02:00
parent a0415f73d4
commit 83c726a34f
10 changed files with 98 additions and 47 deletions

View File

@ -347,7 +347,7 @@ endif
libfs_a_SOURCES = \ libfs_a_SOURCES = \
src/fs/Domain.cxx src/fs/Domain.hxx \ src/fs/Domain.cxx src/fs/Domain.hxx \
src/fs/Limits.hxx \ src/fs/Limits.hxx \
src/fs/Traits.hxx \ src/fs/Traits.cxx src/fs/Traits.hxx \
src/fs/Config.cxx src/fs/Config.hxx \ src/fs/Config.cxx src/fs/Config.hxx \
src/fs/Charset.cxx src/fs/Charset.hxx \ src/fs/Charset.cxx src/fs/Charset.hxx \
src/fs/Path.cxx src/fs/Path.hxx \ src/fs/Path.cxx src/fs/Path.hxx \

View File

@ -24,6 +24,7 @@
#include "DatabaseLock.hxx" #include "DatabaseLock.hxx"
#include "SongSort.hxx" #include "SongSort.hxx"
#include "Song.hxx" #include "Song.hxx"
#include "fs/Traits.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
extern "C" { extern "C" {
@ -112,14 +113,8 @@ const char *
Directory::GetName() const Directory::GetName() const
{ {
assert(!IsRoot()); assert(!IsRoot());
assert(path != nullptr);
const char *slash = strrchr(path, '/'); return PathTraits::GetBaseUTF8(path);
assert((slash == nullptr) == parent->IsRoot());
return slash != nullptr
? slash + 1
: path;
} }
Directory * Directory *

View File

@ -33,11 +33,10 @@
#include "Client.hxx" #include "Client.hxx"
#include "InputStream.hxx" #include "InputStream.hxx"
#include "Song.hxx" #include "Song.hxx"
#include "fs/Traits.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
#include "thread/Cond.hxx" #include "thread/Cond.hxx"
#include <glib.h>
void void
playlist_print_uris(Client &client, const playlist &playlist) playlist_print_uris(Client &client, const playlist &playlist)
{ {
@ -150,11 +149,14 @@ static void
playlist_provider_print(Client &client, const char *uri, playlist_provider_print(Client &client, const char *uri,
SongEnumerator &e, bool detail) SongEnumerator &e, bool detail)
{ {
Song *song; const std::string base_uri = uri != nullptr
char *base_uri = uri != nullptr ? g_path_get_dirname(uri) : nullptr; ? PathTraits::GetParentUTF8(uri)
: std::string(".");
Song *song;
while ((song = e.NextSong()) != nullptr) { while ((song = e.NextSong()) != nullptr) {
song = playlist_check_translate_song(song, base_uri, false); song = playlist_check_translate_song(song, base_uri.c_str(),
false);
if (song == nullptr) if (song == nullptr)
continue; continue;
@ -165,8 +167,6 @@ playlist_provider_print(Client &client, const char *uri,
song->Free(); song->Free();
} }
g_free(base_uri);
} }
bool bool

View File

@ -27,8 +27,7 @@
#include "SongEnumerator.hxx" #include "SongEnumerator.hxx"
#include "Song.hxx" #include "Song.hxx"
#include "thread/Cond.hxx" #include "thread/Cond.hxx"
#include "fs/Traits.hxx"
#include <glib.h>
PlaylistResult PlaylistResult
playlist_load_into_queue(const char *uri, SongEnumerator &e, playlist_load_into_queue(const char *uri, SongEnumerator &e,
@ -36,10 +35,11 @@ playlist_load_into_queue(const char *uri, SongEnumerator &e,
playlist &dest, player_control &pc, playlist &dest, player_control &pc,
bool secure) bool secure)
{ {
PlaylistResult result; const std::string base_uri = uri != nullptr
Song *song; ? PathTraits::GetParentUTF8(uri)
char *base_uri = uri != nullptr ? g_path_get_dirname(uri) : nullptr; : std::string(".");
Song *song;
for (unsigned i = 0; for (unsigned i = 0;
i < end_index && (song = e.NextSong()) != nullptr; i < end_index && (song = e.NextSong()) != nullptr;
++i) { ++i) {
@ -49,19 +49,16 @@ playlist_load_into_queue(const char *uri, SongEnumerator &e,
continue; continue;
} }
song = playlist_check_translate_song(song, base_uri, secure); song = playlist_check_translate_song(song, base_uri.c_str(),
secure);
if (song == nullptr) if (song == nullptr)
continue; continue;
result = dest.AppendSong(pc, song); PlaylistResult result = dest.AppendSong(pc, song);
song->Free(); song->Free();
if (result != PlaylistResult::SUCCESS) { if (result != PlaylistResult::SUCCESS)
g_free(base_uri);
return result; return result;
} }
}
g_free(base_uri);
return PlaylistResult::SUCCESS; return PlaylistResult::SUCCESS;
} }

View File

@ -142,9 +142,9 @@ playlist_check_translate_song(Song *song, const char *base_uri,
} }
if (base_uri != nullptr && strcmp(base_uri, ".") == 0) if (base_uri != nullptr && strcmp(base_uri, ".") == 0)
/* g_path_get_dirname() returns "." when there is no /* PathTraits::GetParentUTF8() returns "." when there
directory name in the given path; clear that now, is no directory name in the given path; clear that
because it would break the database lookup now, because it would break the database lookup
functions */ functions */
base_uri = nullptr; base_uri = nullptr;

View File

@ -458,7 +458,7 @@ update_uri(const char *uri)
if (parent == nullptr) if (parent == nullptr)
return; return;
char *name = g_path_get_basename(uri); const char *name = PathTraits::GetBaseUTF8(uri);
struct stat st; struct stat st;
if (!skip_symlink(parent, name) && if (!skip_symlink(parent, name) &&
@ -466,8 +466,6 @@ update_uri(const char *uri)
update_directory_child(*parent, name, &st); update_directory_child(*parent, name, &st);
else else
modified |= delete_name_in(*parent, name); modified |= delete_name_in(*parent, name);
g_free(name);
} }
bool bool

View File

@ -32,12 +32,13 @@
#include "util/RefCount.hxx" #include "util/RefCount.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
#include "util/Domain.hxx" #include "util/Domain.hxx"
#include "fs/Traits.hxx"
#include <bzlib.h>
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
#include <glib.h>
#include <bzlib.h>
#ifdef HAVE_OLDER_BZIP2 #ifdef HAVE_OLDER_BZIP2
#define BZ2_bzDecompressInit bzDecompressInit #define BZ2_bzDecompressInit bzDecompressInit
@ -48,17 +49,17 @@ class Bzip2ArchiveFile final : public ArchiveFile {
public: public:
RefCount ref; RefCount ref;
char *const name; std::string name;
struct input_stream *const istream; struct input_stream *const istream;
Bzip2ArchiveFile(const char *path, input_stream *_is) Bzip2ArchiveFile(const char *path, input_stream *_is)
:ArchiveFile(bz2_archive_plugin), :ArchiveFile(bz2_archive_plugin),
name(g_path_get_basename(path)), name(PathTraits::GetBaseUTF8(path)),
istream(_is) { istream(_is) {
// remove .bz2 suffix // remove .bz2 suffix
size_t len = strlen(name); const size_t len = name.length();
if (len > 4) if (len > 4)
name[len - 4] = 0; name.erase(len - 4);
} }
~Bzip2ArchiveFile() { ~Bzip2ArchiveFile() {
@ -73,7 +74,6 @@ public:
if (!ref.Decrement()) if (!ref.Decrement())
return; return;
g_free(name);
delete this; delete this;
} }
@ -82,7 +82,7 @@ public:
} }
virtual void Visit(ArchiveVisitor &visitor) override { virtual void Visit(ArchiveVisitor &visitor) override {
visitor.VisitArchiveEntry(name); visitor.VisitArchiveEntry(name.c_str());
} }
virtual input_stream *OpenStream(const char *path, virtual input_stream *OpenStream(const char *path,

45
src/fs/Traits.cxx Normal file
View File

@ -0,0 +1,45 @@
/*
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include "Traits.hxx"
#include <string.h>
const char *
PathTraits::GetBaseUTF8(const char *p)
{
assert(p != nullptr);
const char *slash = strrchr(p, SEPARATOR_UTF8);
return slash != nullptr
? slash + 1
: p;
}
std::string
PathTraits::GetParentUTF8(const char *p)
{
assert(p != nullptr);
const char *slash = strrchr(p, SEPARATOR_UTF8);
return slash != nullptr
? std::string(p, slash)
: std::string(".");
}

View File

@ -27,6 +27,8 @@
#include <glib.h> #include <glib.h>
#endif #endif
#include <string>
#include <assert.h> #include <assert.h>
class Error; class Error;
@ -84,6 +86,21 @@ struct PathTraits {
return IsSeparatorUTF8(*p); return IsSeparatorUTF8(*p);
#endif #endif
} }
/**
* Determine the "base" file name of the given UTF-8 path.
* The return value points inside the given string.
*/
gcc_pure gcc_nonnull_all
static const char *GetBaseUTF8(const char *p);
/**
* Determine the "parent" file name of the given UTF-8 path.
* As a special case, returns the string "." if there is no
* separator in the given input string.
*/
gcc_pure gcc_nonnull_all
static std::string GetParentUTF8(const char *p);
}; };
#endif #endif

View File

@ -48,7 +48,7 @@ public:
* sheet must always point to the song file it is contained * sheet must always point to the song file it is contained
* in. * in.
*/ */
char *filename; std::string filename;
/** /**
* The value of the file's "CUESHEET" tag. * The value of the file's "CUESHEET" tag.
@ -64,13 +64,12 @@ public:
public: public:
EmbeddedCuePlaylist() EmbeddedCuePlaylist()
:filename(nullptr), cuesheet(nullptr), parser(nullptr) { :cuesheet(nullptr), parser(nullptr) {
} }
virtual ~EmbeddedCuePlaylist() { virtual ~EmbeddedCuePlaylist() {
delete parser; delete parser;
g_free(cuesheet); g_free(cuesheet);
g_free(filename);
} }
virtual Song *NextSong() override; virtual Song *NextSong() override;
@ -116,7 +115,7 @@ embcue_playlist_open_uri(const char *uri,
return NULL; return NULL;
} }
playlist->filename = g_path_get_basename(uri); playlist->filename = PathTraits::GetBaseUTF8(uri);
playlist->next = playlist->cuesheet; playlist->next = playlist->cuesheet;
playlist->parser = new CueParser(); playlist->parser = new CueParser();
@ -146,13 +145,13 @@ EmbeddedCuePlaylist::NextSong()
parser->Feed(line); parser->Feed(line);
song = parser->Get(); song = parser->Get();
if (song != NULL) if (song != NULL)
return song->ReplaceURI(filename); return song->ReplaceURI(filename.c_str());
} }
parser->Finish(); parser->Finish();
song = parser->Get(); song = parser->Get();
if (song != NULL) if (song != NULL)
song = song->ReplaceURI(filename); song = song->ReplaceURI(filename.c_str());
return song; return song;
} }