song: allocate the result of song_get_url()

This commit is contained in:
Max Kellermann 2009-01-04 19:09:34 +01:00
parent ea8ae68e6f
commit fed719197c
13 changed files with 110 additions and 85 deletions

View File

@ -455,8 +455,7 @@ static bool
wavpack_open_wvc(struct decoder *decoder, struct input_stream *is_wvc, wavpack_open_wvc(struct decoder *decoder, struct input_stream *is_wvc,
struct wavpack_input *wpi) struct wavpack_input *wpi)
{ {
char tmp[MPD_PATH_MAX]; char *utf8url;
const char *utf8url;
char *wvc_url = NULL; char *wvc_url = NULL;
bool ret; bool ret;
char first_byte; char first_byte;
@ -466,12 +465,14 @@ wavpack_open_wvc(struct decoder *decoder, struct input_stream *is_wvc,
* As we use dc->utf8url, this function will be bad for * As we use dc->utf8url, this function will be bad for
* single files. utf8url is not absolute file path :/ * single files. utf8url is not absolute file path :/
*/ */
utf8url = decoder_get_url(decoder, tmp); utf8url = decoder_get_uri(decoder);
if (utf8url == NULL) { if (utf8url == NULL) {
return false; return false;
} }
wvc_url = g_strconcat(utf8url, "c", NULL); wvc_url = g_strconcat(utf8url, "c", NULL);
g_free(utf8url);
ret = input_stream_open(is_wvc, wvc_url); ret = input_stream_open(is_wvc, wvc_url);
g_free(wvc_url); g_free(wvc_url);

View File

@ -57,10 +57,9 @@ void decoder_initialized(struct decoder * decoder,
notify_signal(&pc.notify); notify_signal(&pc.notify);
} }
const char *decoder_get_url(G_GNUC_UNUSED struct decoder * decoder, char *decoder_get_uri(G_GNUC_UNUSED struct decoder *decoder)
char * buffer)
{ {
return song_get_url(dc.current_song, buffer); return song_get_uri(dc.current_song);
} }
enum decoder_command decoder_get_command(G_GNUC_UNUSED struct decoder * decoder) enum decoder_command decoder_get_command(G_GNUC_UNUSED struct decoder * decoder)

View File

@ -108,7 +108,13 @@ void decoder_initialized(struct decoder * decoder,
const struct audio_format *audio_format, const struct audio_format *audio_format,
bool seekable, float total_time); bool seekable, float total_time);
const char *decoder_get_url(struct decoder * decoder, char * buffer); /**
* Returns the URI of the current song in UTF-8 encoding.
*
* The return value is allocated on the heap, and must be freed by the
* caller.
*/
char *decoder_get_uri(struct decoder *decoder);
enum decoder_command decoder_get_command(struct decoder * decoder); enum decoder_command decoder_get_command(struct decoder * decoder);

View File

@ -208,11 +208,8 @@ static void decoder_run(void)
if (song_is_file(song)) if (song_is_file(song))
uri = map_song_fs(song); uri = map_song_fs(song);
else { else
char buffer[MPD_PATH_MAX]; uri = song_get_uri(song);
uri = g_strdup(song_get_url(song, buffer));
}
if (uri == NULL) { if (uri == NULL) {
dc.state = DECODE_STATE_ERROR; dc.state = DECODE_STATE_ERROR;

View File

@ -135,10 +135,12 @@ strstrSearchTag(struct song *song, enum tag_type type, char *str)
int8_t visitedTypes[TAG_NUM_OF_ITEM_TYPES] = { 0 }; int8_t visitedTypes[TAG_NUM_OF_ITEM_TYPES] = { 0 };
if (type == LOCATE_TAG_FILE_TYPE || type == LOCATE_TAG_ANY_TYPE) { if (type == LOCATE_TAG_FILE_TYPE || type == LOCATE_TAG_ANY_TYPE) {
char path_max_tmp[MPD_PATH_MAX], *p; char *uri, *p;
uri = song_get_uri(song);
p = g_utf8_casefold(uri, -1);
g_free(uri);
song_get_url(song, path_max_tmp);
p = g_utf8_casefold(path_max_tmp, -1);
if (strstr(p, str)) if (strstr(p, str))
ret = 1; ret = 1;
g_free(p); g_free(p);
@ -196,9 +198,13 @@ tagItemFoundAndMatches(struct song *song, enum tag_type type, char *str)
int8_t visitedTypes[TAG_NUM_OF_ITEM_TYPES] = { 0 }; int8_t visitedTypes[TAG_NUM_OF_ITEM_TYPES] = { 0 };
if (type == LOCATE_TAG_FILE_TYPE || type == LOCATE_TAG_ANY_TYPE) { if (type == LOCATE_TAG_FILE_TYPE || type == LOCATE_TAG_ANY_TYPE) {
char path_max_tmp[MPD_PATH_MAX]; char *uri = song_get_uri(song);
if (0 == strcmp(str, song_get_url(song, path_max_tmp))) bool matches = strcmp(str, uri);
g_free(uri);
if (matches)
return 1; return 1;
if (type == LOCATE_TAG_FILE_TYPE) if (type == LOCATE_TAG_FILE_TYPE)
return 0; return 0;
} }

View File

@ -150,15 +150,10 @@ enum player_error getPlayerError(void)
return pc.error; return pc.error;
} }
static const char * static char *
pc_errored_song_uri(void) pc_errored_song_uri(void)
{ {
char path_max_tmp[MPD_PATH_MAX]; return song_get_uri(pc.errored_song);
if (pc.errored_song == NULL)
return "?";
return song_get_url(pc.errored_song, path_max_tmp);
} }
char *getPlayerErrorStr(void) char *getPlayerErrorStr(void)
@ -166,6 +161,8 @@ char *getPlayerErrorStr(void)
/* static OK here, only one user in main task */ /* static OK here, only one user in main task */
static char error[MPD_PATH_MAX + 64]; /* still too much */ static char error[MPD_PATH_MAX + 64]; /* still too much */
static const size_t errorlen = sizeof(error); static const size_t errorlen = sizeof(error);
char *uri;
*error = '\0'; /* likely */ *error = '\0'; /* likely */
switch (pc.error) { switch (pc.error) {
@ -173,23 +170,32 @@ char *getPlayerErrorStr(void)
break; break;
case PLAYER_ERROR_FILENOTFOUND: case PLAYER_ERROR_FILENOTFOUND:
uri = pc_errored_song_uri();
snprintf(error, errorlen, snprintf(error, errorlen,
"file \"%s\" does not exist or is inaccessible", "file \"%s\" does not exist or is inaccessible", uri);
pc_errored_song_uri()); g_free(uri);
break; break;
case PLAYER_ERROR_FILE: case PLAYER_ERROR_FILE:
snprintf(error, errorlen, "problems decoding \"%s\"", uri = pc_errored_song_uri();
pc_errored_song_uri()); snprintf(error, errorlen, "problems decoding \"%s\"", uri);
g_free(uri);
break; break;
case PLAYER_ERROR_AUDIO: case PLAYER_ERROR_AUDIO:
strcpy(error, "problems opening audio device"); strcpy(error, "problems opening audio device");
break; break;
case PLAYER_ERROR_SYSTEM: case PLAYER_ERROR_SYSTEM:
strcpy(error, "system error occured"); strcpy(error, "system error occured");
break; break;
case PLAYER_ERROR_UNKTYPE: case PLAYER_ERROR_UNKTYPE:
snprintf(error, errorlen, "file type of \"%s\" is unknown", uri = pc_errored_song_uri();
pc_errored_song_uri()); snprintf(error, errorlen,
"file type of \"%s\" is unknown", uri);
g_free(uri);
break;
} }
return *error ? error : NULL; return *error ? error : NULL;
} }

View File

@ -178,13 +178,15 @@ static void player_process_command(struct player *player)
if (openAudioDevice(NULL)) { if (openAudioDevice(NULL)) {
pc.state = PLAYER_STATE_PLAY; pc.state = PLAYER_STATE_PLAY;
} else { } else {
char tmp[MPD_PATH_MAX]; char *uri = song_get_uri(dc.next_song);
g_warning("problems opening audio device "
"while playing \"%s\"", uri);
g_free(uri);
assert(dc.next_song == NULL || dc.next_song->url != NULL); assert(dc.next_song == NULL || dc.next_song->url != NULL);
pc.errored_song = dc.next_song; pc.errored_song = dc.next_song;
pc.error = PLAYER_ERROR_AUDIO; pc.error = PLAYER_ERROR_AUDIO;
g_warning("problems opening audio device "
"while playing \"%s\"",
song_get_url(dc.next_song, tmp));
player->paused = true; player->paused = true;
} }
} }
@ -335,13 +337,14 @@ static void do_play(void)
/* the decoder is ready and ok */ /* the decoder is ready and ok */
player.decoder_starting = false; player.decoder_starting = false;
if (!openAudioDevice(&dc.out_audio_format)) { if (!openAudioDevice(&dc.out_audio_format)) {
char tmp[MPD_PATH_MAX]; char *uri = song_get_uri(dc.next_song);
g_warning("problems opening audio device "
"while playing \"%s\"", uri);
g_free(uri);
assert(dc.next_song == NULL || dc.next_song->url != NULL); assert(dc.next_song == NULL || dc.next_song->url != NULL);
pc.errored_song = dc.next_song; pc.errored_song = dc.next_song;
pc.error = PLAYER_ERROR_AUDIO; pc.error = PLAYER_ERROR_AUDIO;
g_warning("problems opening audio device "
"while playing \"%s\"",
song_get_url(dc.next_song, tmp));
break; break;
} }

View File

@ -224,20 +224,20 @@ void clearPlaylist(void)
void showPlaylist(struct client *client) void showPlaylist(struct client *client)
{ {
char path_max_tmp[MPD_PATH_MAX]; for (unsigned i = 0; i < playlist.length; i++) {
char *uri = song_get_uri(playlist.songs[i]);
for (unsigned i = 0; i < playlist.length; i++) client_printf(client, "%i:%s\n", i, uri);
client_printf(client, "%i:%s\n", i, g_free(uri);
song_get_url(playlist.songs[i], path_max_tmp)); }
} }
static void playlist_save(FILE *fp) static void playlist_save(FILE *fp)
{ {
char path_max_tmp[MPD_PATH_MAX]; for (unsigned i = 0; i < playlist.length; i++) {
char *uri = song_get_uri(playlist.songs[i]);
for (unsigned i = 0; i < playlist.length; i++) fprintf(fp, "%i:%s\n", i, uri);
fprintf(fp, "%i:%s\n", i, g_free(uri);
song_get_url(playlist.songs[i], path_max_tmp)); }
} }
void savePlaylistState(FILE *fp) void savePlaylistState(FILE *fp)
@ -483,26 +483,30 @@ static void swapSongs(unsigned song1, unsigned song2)
static void queueNextSongInPlaylist(void) static void queueNextSongInPlaylist(void)
{ {
char path_max_tmp[MPD_PATH_MAX];
if (playlist.current < (int)playlist.length - 1) { if (playlist.current < (int)playlist.length - 1) {
char *uri;
playlist.queued = playlist.current + 1; playlist.queued = playlist.current + 1;
uri = song_get_uri(playlist. songs[playlist.order[playlist.queued]]);
g_debug("playlist: queue song %i:\"%s\"", g_debug("playlist: queue song %i:\"%s\"",
playlist.queued, playlist.queued, uri);
song_get_url(playlist. g_free(uri);
songs[playlist.order[playlist.queued]],
path_max_tmp));
queueSong(playlist.songs[playlist.order[playlist.queued]]); queueSong(playlist.songs[playlist.order[playlist.queued]]);
} else if (playlist.length && playlist.repeat) { } else if (playlist.length && playlist.repeat) {
char *uri;
if (playlist.length > 1 && playlist.random) { if (playlist.length > 1 && playlist.random) {
randomizeOrder(0, playlist.length - 1); randomizeOrder(0, playlist.length - 1);
} }
playlist.queued = 0; playlist.queued = 0;
uri = song_get_uri(playlist. songs[playlist.order[playlist.queued]]);
g_debug("playlist: queue song %i:\"%s\"", g_debug("playlist: queue song %i:\"%s\"",
playlist.queued, playlist.queued, uri);
song_get_url(playlist. g_free(uri);
songs[playlist.order[playlist.queued]],
path_max_tmp));
queueSong(playlist.songs[playlist.order[playlist.queued]]); queueSong(playlist.songs[playlist.order[playlist.queued]]);
} }
} }
@ -783,15 +787,15 @@ void stopPlaylist(void)
static void playPlaylistOrderNumber(int orderNum) static void playPlaylistOrderNumber(int orderNum)
{ {
char path_max_tmp[MPD_PATH_MAX]; char *uri;
playlist_state = PLAYLIST_STATE_PLAY; playlist_state = PLAYLIST_STATE_PLAY;
playlist_noGoToNext = 0; playlist_noGoToNext = 0;
playlist.queued = -1; playlist.queued = -1;
g_debug("playlist: play %i:\"%s\"", orderNum, uri = song_get_uri(playlist.songs[playlist.order[orderNum]]);
song_get_url(playlist.songs[playlist.order[orderNum]], g_debug("playlist: play %i:\"%s\"", orderNum, uri);
path_max_tmp)); g_free(uri);
playerPlay(playlist.songs[playlist.order[orderNum]]); playerPlay(playlist.songs[playlist.order[orderNum]]);
playlist.current = orderNum; playlist.current = orderNum;

View File

@ -29,8 +29,6 @@
void void
playlist_print_song(FILE *file, const struct song *song) playlist_print_song(FILE *file, const struct song *song)
{ {
char tmp1[MPD_PATH_MAX], tmp2[MPD_PATH_MAX];
if (playlist_saveAbsolutePaths && song_in_database(song)) { if (playlist_saveAbsolutePaths && song_in_database(song)) {
char *path = map_song_fs(song); char *path = map_song_fs(song);
if (path != NULL) { if (path != NULL) {
@ -38,9 +36,13 @@ playlist_print_song(FILE *file, const struct song *song)
g_free(path); g_free(path);
} }
} else { } else {
song_get_url(song, tmp1); char *uri = song_get_uri(song);
utf8_to_fs_charset(tmp2, tmp1); char tmp2[MPD_PATH_MAX];
fprintf(file, "%s\n", tmp2);
utf8_to_fs_charset(tmp2, uri);
g_free(uri);
fprintf(file, "%s\n", uri);
} }
} }

View File

@ -176,16 +176,14 @@ song_file_update_inarchive(struct song *song)
} }
char * char *
song_get_url(const struct song *song, char *path_max_tmp) song_get_uri(const struct song *song)
{ {
assert(song != NULL); assert(song != NULL);
assert(*song->url); assert(*song->url);
if (!song_in_database(song) || directory_is_root(song->parent)) if (!song_in_database(song) || directory_is_root(song->parent))
strcpy(path_max_tmp, song->url); return g_strdup(song->url);
else else
pfx_dir(path_max_tmp, song->url, strlen(song->url), return g_strconcat(directory_get_path(song->parent),
directory_get_path(song->parent), "/", song->url, NULL);
strlen(directory_get_path(song->parent)));
return path_max_tmp;
} }

View File

@ -61,14 +61,15 @@ song_file_update(struct song *song);
bool bool
song_file_update_inarchive(struct song *song); song_file_update_inarchive(struct song *song);
/* /**
* song_get_url - Returns a path of a song in UTF8-encoded form * Returns the URI of the song in UTF-8 encoding, including its
* path_max_tmp is the argument that the URL is written to, this * location within the music directory.
* buffer is assumed to be MPD_PATH_MAX or greater (including *
* terminating '\0'). * The return value is allocated on the heap, and must be freed by the
* caller.
*/ */
char * char *
song_get_url(const struct song *song, char *path_max_tmp); song_get_uri(const struct song *song);
static inline bool static inline bool
song_in_database(const struct song *song) song_in_database(const struct song *song)

View File

@ -141,7 +141,6 @@ spl_load(const char *utf8path)
FILE *file; FILE *file;
GPtrArray *list; GPtrArray *list;
char buffer[MPD_PATH_MAX]; char buffer[MPD_PATH_MAX];
char path_max_tmp[MPD_PATH_MAX];
char *path_fs; char *path_fs;
if (!is_valid_playlist_name(utf8path)) if (!is_valid_playlist_name(utf8path))
@ -177,10 +176,11 @@ spl_load(const char *utf8path)
if (song == NULL) if (song == NULL)
continue; continue;
s = song_get_url(song, path_max_tmp); s = song_get_uri(song);
} } else
s = g_strdup(s);
g_ptr_array_add(list, g_strdup(s)); g_ptr_array_add(list, s);
if (list->len >= playlist_max_length) if (list->len >= playlist_max_length)
break; break;

View File

@ -699,8 +699,10 @@ static void reap_update_task(void)
cond_enter(&delete_cond); cond_enter(&delete_cond);
if (delete) { if (delete) {
char tmp[MPD_PATH_MAX]; char *tmp = song_get_uri(delete);
g_debug("removing: %s", song_get_url(delete, tmp)); g_debug("removing: %s", tmp);
g_free(tmp);
deleteASongFromPlaylist(delete); deleteASongFromPlaylist(delete);
delete = NULL; delete = NULL;
cond_signal_sync(&delete_cond); cond_signal_sync(&delete_cond);