Song: add function song_dup_detached()
Initial support for "detached" songs that come from the database, but are private copies.
This commit is contained in:
parent
c2e4fe983d
commit
916a020173
36
src/Song.cxx
36
src/Song.cxx
|
@ -29,6 +29,8 @@ extern "C" {
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
struct directory detached_root;
|
||||
|
||||
static struct song *
|
||||
song_alloc(const char *uri, struct directory *parent)
|
||||
{
|
||||
|
@ -76,6 +78,27 @@ song_replace_uri(struct song *old_song, const char *uri)
|
|||
return new_song;
|
||||
}
|
||||
|
||||
struct song *
|
||||
song_dup_detached(const struct song *src)
|
||||
{
|
||||
assert(src != nullptr);
|
||||
|
||||
struct song *song;
|
||||
if (song_in_database(src)) {
|
||||
char *uri = song_get_uri(src);
|
||||
song = song_alloc(uri, &detached_root);
|
||||
g_free(uri);
|
||||
} else
|
||||
song = song_alloc(src->uri, nullptr);
|
||||
|
||||
song->tag = tag_dup(src->tag);
|
||||
song->mtime = src->mtime;
|
||||
song->start_ms = src->start_ms;
|
||||
song->end_ms = src->end_ms;
|
||||
|
||||
return song;
|
||||
}
|
||||
|
||||
void
|
||||
song_free(struct song *song)
|
||||
{
|
||||
|
@ -107,6 +130,19 @@ song_equals(const struct song *a, const struct song *b)
|
|||
assert(a != nullptr);
|
||||
assert(b != nullptr);
|
||||
|
||||
if (a->parent != nullptr && b->parent != nullptr &&
|
||||
!directory_equals(*a->parent, *b->parent) &&
|
||||
(a->parent == &detached_root || b->parent == &detached_root)) {
|
||||
/* must compare the full URI if one of the objects is
|
||||
"detached" */
|
||||
char *au = song_get_uri(a);
|
||||
char *bu = song_get_uri(b);
|
||||
const bool result = strcmp(au, bu) == 0;
|
||||
g_free(bu);
|
||||
g_free(au);
|
||||
return result;
|
||||
}
|
||||
|
||||
return directory_is_same(a->parent, b->parent) &&
|
||||
strcmp(a->uri, b->uri) == 0;
|
||||
}
|
||||
|
|
21
src/mapper.c
21
src/mapper.c
|
@ -219,13 +219,32 @@ map_directory_child_fs(const struct directory *directory, const char *name)
|
|||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a song object that was created by song_dup_detached(). It does
|
||||
* not have a real parent directory, only the dummy object
|
||||
* #detached_root.
|
||||
*/
|
||||
static char *
|
||||
map_detached_song_fs(const char *uri_utf8)
|
||||
{
|
||||
char *uri_fs = utf8_to_fs_charset(uri_utf8);
|
||||
if (uri_fs == NULL)
|
||||
return NULL;
|
||||
|
||||
char *path = g_build_filename(music_dir_fs, uri_fs, NULL);
|
||||
g_free(uri_fs);
|
||||
return path;
|
||||
}
|
||||
|
||||
char *
|
||||
map_song_fs(const struct song *song)
|
||||
{
|
||||
assert(song_is_file(song));
|
||||
|
||||
if (song_in_database(song))
|
||||
return map_directory_child_fs(song->parent, song->uri);
|
||||
return song_is_detached(song)
|
||||
? map_detached_song_fs(song->uri)
|
||||
: map_directory_child_fs(song->parent, song->uri);
|
||||
else
|
||||
return utf8_to_fs_charset(song->uri);
|
||||
}
|
||||
|
|
25
src/song.h
25
src/song.h
|
@ -23,6 +23,7 @@
|
|||
#include "util/list.h"
|
||||
#include "gcc.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/time.h>
|
||||
|
@ -59,6 +60,12 @@ struct song {
|
|||
char uri[sizeof(int)];
|
||||
};
|
||||
|
||||
/**
|
||||
* A dummy #directory instance that is used for "detached" song
|
||||
* copies.
|
||||
*/
|
||||
extern struct directory detached_root;
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/** allocate a new song with a remote URL */
|
||||
|
@ -86,6 +93,15 @@ song_file_load(const char *path, struct directory *parent);
|
|||
struct song *
|
||||
song_replace_uri(struct song *song, const char *uri);
|
||||
|
||||
/**
|
||||
* Creates a duplicate of the song object. If the object is in the
|
||||
* database, it creates a "detached" copy of this song, see
|
||||
* song_is_detached().
|
||||
*/
|
||||
gcc_malloc
|
||||
struct song *
|
||||
song_dup_detached(const struct song *src);
|
||||
|
||||
void
|
||||
song_free(struct song *song);
|
||||
|
||||
|
@ -101,6 +117,15 @@ song_is_file(const struct song *song)
|
|||
return song_in_database(song) || song->uri[0] == '/';
|
||||
}
|
||||
|
||||
static inline bool
|
||||
song_is_detached(const struct song *song)
|
||||
{
|
||||
assert(song != NULL);
|
||||
assert(song_in_database(song));
|
||||
|
||||
return song->parent == &detached_root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if both objects refer to the same physical song.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue