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 = \
src/fs/Domain.cxx src/fs/Domain.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/Charset.cxx src/fs/Charset.hxx \
src/fs/Path.cxx src/fs/Path.hxx \

View File

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

View File

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

View File

@ -27,8 +27,7 @@
#include "SongEnumerator.hxx"
#include "Song.hxx"
#include "thread/Cond.hxx"
#include <glib.h>
#include "fs/Traits.hxx"
PlaylistResult
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,
bool secure)
{
PlaylistResult result;
Song *song;
char *base_uri = uri != nullptr ? g_path_get_dirname(uri) : nullptr;
const std::string base_uri = uri != nullptr
? PathTraits::GetParentUTF8(uri)
: std::string(".");
Song *song;
for (unsigned i = 0;
i < end_index && (song = e.NextSong()) != nullptr;
++i) {
@ -49,20 +49,17 @@ playlist_load_into_queue(const char *uri, SongEnumerator &e,
continue;
}
song = playlist_check_translate_song(song, base_uri, secure);
song = playlist_check_translate_song(song, base_uri.c_str(),
secure);
if (song == nullptr)
continue;
result = dest.AppendSong(pc, song);
PlaylistResult result = dest.AppendSong(pc, song);
song->Free();
if (result != PlaylistResult::SUCCESS) {
g_free(base_uri);
if (result != PlaylistResult::SUCCESS)
return result;
}
}
g_free(base_uri);
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)
/* g_path_get_dirname() returns "." when there is no
directory name in the given path; clear that now,
because it would break the database lookup
/* PathTraits::GetParentUTF8() returns "." when there
is no directory name in the given path; clear that
now, because it would break the database lookup
functions */
base_uri = nullptr;

View File

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

View File

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

View File

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