Directory: turn functions to methods
This commit is contained in:
parent
0c245bc271
commit
0eb05b827f
@ -128,9 +128,7 @@ db_get_directory(const char *name)
|
|||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
return music_root;
|
return music_root;
|
||||||
|
|
||||||
struct directory *directory =
|
return music_root->LookupDirectory(name);
|
||||||
directory_lookup_directory(music_root, name);
|
|
||||||
return directory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct song *
|
struct song *
|
||||||
|
@ -41,9 +41,8 @@ extern "C" {
|
|||||||
static bool
|
static bool
|
||||||
PrintDirectory(struct client *client, const directory &directory)
|
PrintDirectory(struct client *client, const directory &directory)
|
||||||
{
|
{
|
||||||
if (!directory_is_root(&directory))
|
if (!directory.IsRoot())
|
||||||
client_printf(client, "directory: %s\n",
|
client_printf(client, "directory: %s\n", directory.GetPath());
|
||||||
directory_get_path(&directory));
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -53,11 +52,11 @@ print_playlist_in_directory(struct client *client,
|
|||||||
const directory &directory,
|
const directory &directory,
|
||||||
const char *name_utf8)
|
const char *name_utf8)
|
||||||
{
|
{
|
||||||
if (directory_is_root(&directory))
|
if (directory.IsRoot())
|
||||||
client_printf(client, "playlist: %s\n", name_utf8);
|
client_printf(client, "playlist: %s\n", name_utf8);
|
||||||
else
|
else
|
||||||
client_printf(client, "playlist: %s/%s\n",
|
client_printf(client, "playlist: %s/%s\n",
|
||||||
directory_get_path(&directory), name_utf8);
|
directory.GetPath(), name_utf8);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -56,7 +56,7 @@ directory_allocate(const char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct directory *
|
struct directory *
|
||||||
directory_new(const char *path, struct directory *parent)
|
directory::NewGeneric(const char *path, struct directory *parent)
|
||||||
{
|
{
|
||||||
assert(path != NULL);
|
assert(path != NULL);
|
||||||
assert((*path == 0) == (parent == NULL));
|
assert((*path == 0) == (parent == NULL));
|
||||||
@ -69,124 +69,121 @@ directory_new(const char *path, struct directory *parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
directory_free(struct directory *directory)
|
directory::Free()
|
||||||
{
|
{
|
||||||
playlist_vector_deinit(&directory->playlists);
|
playlist_vector_deinit(&playlists);
|
||||||
|
|
||||||
struct song *song, *ns;
|
struct song *song, *ns;
|
||||||
directory_for_each_song_safe(song, ns, directory)
|
directory_for_each_song_safe(song, ns, this)
|
||||||
song_free(song);
|
song_free(song);
|
||||||
|
|
||||||
struct directory *child, *n;
|
struct directory *child, *n;
|
||||||
directory_for_each_child_safe(child, n, directory)
|
directory_for_each_child_safe(child, n, this)
|
||||||
directory_free(child);
|
child->Free();
|
||||||
|
|
||||||
g_free(directory);
|
g_free(this);
|
||||||
/* this resets last dir returned */
|
|
||||||
/*directory_get_path(NULL); */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
directory_delete(struct directory *directory)
|
directory::Delete()
|
||||||
{
|
{
|
||||||
assert(holding_db_lock());
|
assert(holding_db_lock());
|
||||||
assert(directory != NULL);
|
assert(parent != nullptr);
|
||||||
assert(directory->parent != NULL);
|
|
||||||
|
|
||||||
list_del(&directory->siblings);
|
list_del(&siblings);
|
||||||
directory_free(directory);
|
Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
directory_get_name(const struct directory *directory)
|
directory::GetName() const
|
||||||
{
|
{
|
||||||
assert(!directory_is_root(directory));
|
assert(!IsRoot());
|
||||||
assert(directory->path != NULL);
|
assert(path != nullptr);
|
||||||
|
|
||||||
const char *slash = strrchr(directory->path, '/');
|
const char *slash = strrchr(path, '/');
|
||||||
assert((slash == NULL) == directory_is_root(directory->parent));
|
assert((slash == nullptr) == parent->IsRoot());
|
||||||
|
|
||||||
return slash != NULL
|
return slash != NULL
|
||||||
? slash + 1
|
? slash + 1
|
||||||
: directory->path;
|
: path;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct directory *
|
struct directory *
|
||||||
directory_new_child(struct directory *parent, const char *name_utf8)
|
directory::CreateChild(const char *name_utf8)
|
||||||
{
|
{
|
||||||
assert(holding_db_lock());
|
assert(holding_db_lock());
|
||||||
assert(parent != NULL);
|
|
||||||
assert(name_utf8 != NULL);
|
assert(name_utf8 != NULL);
|
||||||
assert(*name_utf8 != 0);
|
assert(*name_utf8 != 0);
|
||||||
|
|
||||||
char *allocated;
|
char *allocated;
|
||||||
const char *path_utf8;
|
const char *path_utf8;
|
||||||
if (directory_is_root(parent)) {
|
if (IsRoot()) {
|
||||||
allocated = NULL;
|
allocated = NULL;
|
||||||
path_utf8 = name_utf8;
|
path_utf8 = name_utf8;
|
||||||
} else {
|
} else {
|
||||||
allocated = g_strconcat(directory_get_path(parent),
|
allocated = g_strconcat(GetPath(),
|
||||||
"/", name_utf8, NULL);
|
"/", name_utf8, NULL);
|
||||||
path_utf8 = allocated;
|
path_utf8 = allocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct directory *directory = directory_new(path_utf8, parent);
|
directory *child = NewGeneric(path_utf8, this);
|
||||||
g_free(allocated);
|
g_free(allocated);
|
||||||
|
|
||||||
list_add_tail(&directory->siblings, &parent->children);
|
list_add_tail(&child->siblings, &children);
|
||||||
return directory;
|
return child;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct directory *
|
const directory *
|
||||||
directory_get_child(const struct directory *directory, const char *name)
|
directory::FindChild(const char *name) const
|
||||||
{
|
{
|
||||||
assert(holding_db_lock());
|
assert(holding_db_lock());
|
||||||
|
|
||||||
struct directory *child;
|
const struct directory *child;
|
||||||
directory_for_each_child(child, directory)
|
directory_for_each_child(child, this)
|
||||||
if (strcmp(directory_get_name(child), name) == 0)
|
if (strcmp(child->GetName(), name) == 0)
|
||||||
return child;
|
return child;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
directory_prune_empty(struct directory *directory)
|
directory::PruneEmpty()
|
||||||
{
|
{
|
||||||
assert(holding_db_lock());
|
assert(holding_db_lock());
|
||||||
|
|
||||||
struct directory *child, *n;
|
struct directory *child, *n;
|
||||||
directory_for_each_child_safe(child, n, directory) {
|
directory_for_each_child_safe(child, n, this) {
|
||||||
directory_prune_empty(child);
|
child->PruneEmpty();
|
||||||
|
|
||||||
if (directory_is_empty(child))
|
if (child->IsEmpty())
|
||||||
directory_delete(child);
|
child->Delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct directory *
|
struct directory *
|
||||||
directory_lookup_directory(struct directory *directory, const char *uri)
|
directory::LookupDirectory(const char *uri)
|
||||||
{
|
{
|
||||||
assert(holding_db_lock());
|
assert(holding_db_lock());
|
||||||
assert(uri != NULL);
|
assert(uri != NULL);
|
||||||
|
|
||||||
if (isRootDirectory(uri))
|
if (isRootDirectory(uri))
|
||||||
return directory;
|
return this;
|
||||||
|
|
||||||
char *duplicated = g_strdup(uri), *name = duplicated;
|
char *duplicated = g_strdup(uri), *name = duplicated;
|
||||||
|
|
||||||
|
struct directory *d = this;
|
||||||
while (1) {
|
while (1) {
|
||||||
char *slash = strchr(name, '/');
|
char *slash = strchr(name, '/');
|
||||||
if (slash == name) {
|
if (slash == name) {
|
||||||
directory = NULL;
|
d = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slash != NULL)
|
if (slash != NULL)
|
||||||
*slash = '\0';
|
*slash = '\0';
|
||||||
|
|
||||||
directory = directory_get_child(directory, name);
|
d = d->FindChild(name);
|
||||||
if (directory == NULL || slash == NULL)
|
if (d == NULL || slash == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
name = slash + 1;
|
name = slash + 1;
|
||||||
@ -194,42 +191,38 @@ directory_lookup_directory(struct directory *directory, const char *uri)
|
|||||||
|
|
||||||
g_free(duplicated);
|
g_free(duplicated);
|
||||||
|
|
||||||
return directory;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
directory_add_song(struct directory *directory, struct song *song)
|
directory::AddSong(struct song *song)
|
||||||
{
|
{
|
||||||
assert(holding_db_lock());
|
assert(holding_db_lock());
|
||||||
assert(directory != NULL);
|
|
||||||
assert(song != NULL);
|
assert(song != NULL);
|
||||||
assert(song->parent == directory);
|
assert(song->parent == this);
|
||||||
|
|
||||||
list_add_tail(&song->siblings, &directory->songs);
|
list_add_tail(&song->siblings, &songs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
directory_remove_song(G_GNUC_UNUSED struct directory *directory,
|
directory::RemoveSong(struct song *song)
|
||||||
struct song *song)
|
|
||||||
{
|
{
|
||||||
assert(holding_db_lock());
|
assert(holding_db_lock());
|
||||||
assert(directory != NULL);
|
|
||||||
assert(song != NULL);
|
assert(song != NULL);
|
||||||
assert(song->parent == directory);
|
assert(song->parent == this);
|
||||||
|
|
||||||
list_del(&song->siblings);
|
list_del(&song->siblings);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct song *
|
const song *
|
||||||
directory_get_song(const struct directory *directory, const char *name_utf8)
|
directory::FindSong(const char *name_utf8) const
|
||||||
{
|
{
|
||||||
assert(holding_db_lock());
|
assert(holding_db_lock());
|
||||||
assert(directory != NULL);
|
|
||||||
assert(name_utf8 != NULL);
|
assert(name_utf8 != NULL);
|
||||||
|
|
||||||
struct song *song;
|
struct song *song;
|
||||||
directory_for_each_song(song, directory) {
|
directory_for_each_song(song, this) {
|
||||||
assert(song->parent == directory);
|
assert(song->parent == this);
|
||||||
|
|
||||||
if (strcmp(song->uri, name_utf8) == 0)
|
if (strcmp(song->uri, name_utf8) == 0)
|
||||||
return song;
|
return song;
|
||||||
@ -239,29 +232,29 @@ directory_get_song(const struct directory *directory, const char *name_utf8)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct song *
|
struct song *
|
||||||
directory_lookup_song(struct directory *directory, const char *uri)
|
directory::LookupSong(const char *uri)
|
||||||
{
|
{
|
||||||
char *duplicated, *base;
|
char *duplicated, *base;
|
||||||
|
|
||||||
assert(holding_db_lock());
|
assert(holding_db_lock());
|
||||||
assert(directory != NULL);
|
|
||||||
assert(uri != NULL);
|
assert(uri != NULL);
|
||||||
|
|
||||||
duplicated = g_strdup(uri);
|
duplicated = g_strdup(uri);
|
||||||
base = strrchr(duplicated, '/');
|
base = strrchr(duplicated, '/');
|
||||||
|
|
||||||
|
struct directory *d = this;
|
||||||
if (base != NULL) {
|
if (base != NULL) {
|
||||||
*base++ = 0;
|
*base++ = 0;
|
||||||
directory = directory_lookup_directory(directory, duplicated);
|
d = d->LookupDirectory(duplicated);
|
||||||
if (directory == NULL) {
|
if (d == nullptr) {
|
||||||
g_free(duplicated);
|
g_free(duplicated);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
base = duplicated;
|
base = duplicated;
|
||||||
|
|
||||||
struct song *song = directory_get_song(directory, base);
|
struct song *song = d->FindSong(base);
|
||||||
assert(song == NULL || song->parent == directory);
|
assert(song == NULL || song->parent == d);
|
||||||
|
|
||||||
g_free(duplicated);
|
g_free(duplicated);
|
||||||
return song;
|
return song;
|
||||||
@ -278,16 +271,16 @@ directory_cmp(G_GNUC_UNUSED void *priv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
directory_sort(struct directory *directory)
|
directory::Sort()
|
||||||
{
|
{
|
||||||
assert(holding_db_lock());
|
assert(holding_db_lock());
|
||||||
|
|
||||||
list_sort(NULL, &directory->children, directory_cmp);
|
list_sort(NULL, &children, directory_cmp);
|
||||||
song_list_sort(&directory->songs);
|
song_list_sort(&songs);
|
||||||
|
|
||||||
struct directory *child;
|
struct directory *child;
|
||||||
directory_for_each_child(child, directory)
|
directory_for_each_child(child, this)
|
||||||
directory_sort(child);
|
child->Sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -90,6 +90,154 @@ struct directory {
|
|||||||
bool have_stat; /* not needed if ino_t == dev_t == 0 is impossible */
|
bool have_stat; /* not needed if ino_t == dev_t == 0 is impossible */
|
||||||
char path[sizeof(long)];
|
char path[sizeof(long)];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic constructor for #directory object.
|
||||||
|
*/
|
||||||
|
gcc_malloc
|
||||||
|
static directory *NewGeneric(const char *path_utf8, directory *parent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new root #directory object.
|
||||||
|
*/
|
||||||
|
gcc_malloc
|
||||||
|
static directory *NewRoot() {
|
||||||
|
return NewGeneric("", nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free this #directory object (and the whole object tree within it),
|
||||||
|
* assuming it was already removed from the parent.
|
||||||
|
*/
|
||||||
|
void Free();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove this #directory object from its parent and free it. This
|
||||||
|
* must not be called with the root directory.
|
||||||
|
*
|
||||||
|
* Caller must lock the #db_mutex.
|
||||||
|
*/
|
||||||
|
void Delete();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new #directory object as a child of the given one.
|
||||||
|
*
|
||||||
|
* Caller must lock the #db_mutex.
|
||||||
|
*
|
||||||
|
* @param name_utf8 the UTF-8 encoded name of the new sub directory
|
||||||
|
*/
|
||||||
|
gcc_malloc
|
||||||
|
directory *CreateChild(const char *name_utf8);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caller must lock the #db_mutex.
|
||||||
|
*/
|
||||||
|
gcc_pure
|
||||||
|
const directory *FindChild(const char *name) const;
|
||||||
|
|
||||||
|
gcc_pure
|
||||||
|
directory *FindChild(const char *name) {
|
||||||
|
const directory *cthis = this;
|
||||||
|
return const_cast<directory *>(cthis->FindChild(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look up a sub directory, and create the object if it does not
|
||||||
|
* exist.
|
||||||
|
*
|
||||||
|
* Caller must lock the #db_mutex.
|
||||||
|
*/
|
||||||
|
struct directory *MakeChild(const char *name_utf8) {
|
||||||
|
struct directory *child = FindChild(name_utf8);
|
||||||
|
if (child == nullptr)
|
||||||
|
child = CreateChild(name_utf8);
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks up a directory by its relative URI.
|
||||||
|
*
|
||||||
|
* @param uri the relative URI
|
||||||
|
* @return the directory, or NULL if none was found
|
||||||
|
*/
|
||||||
|
gcc_pure
|
||||||
|
directory *LookupDirectory(const char *uri);
|
||||||
|
|
||||||
|
gcc_pure
|
||||||
|
bool IsEmpty() const {
|
||||||
|
return list_empty(&children) &&
|
||||||
|
list_empty(&songs) &&
|
||||||
|
list_empty(&playlists);
|
||||||
|
}
|
||||||
|
|
||||||
|
gcc_pure
|
||||||
|
const char *GetPath() const {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the base name of the directory.
|
||||||
|
*/
|
||||||
|
gcc_pure
|
||||||
|
const char *GetName() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this the root directory of the music database?
|
||||||
|
*/
|
||||||
|
gcc_pure
|
||||||
|
bool IsRoot() const {
|
||||||
|
return parent == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look up a song in this directory by its name.
|
||||||
|
*
|
||||||
|
* Caller must lock the #db_mutex.
|
||||||
|
*/
|
||||||
|
gcc_pure
|
||||||
|
const song *FindSong(const char *name_utf8) const;
|
||||||
|
|
||||||
|
gcc_pure
|
||||||
|
song *FindSong(const char *name_utf8) {
|
||||||
|
const directory *cthis = this;
|
||||||
|
return const_cast<song *>(cthis->FindSong(name_utf8));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks up a song by its relative URI.
|
||||||
|
*
|
||||||
|
* Caller must lock the #db_mutex.
|
||||||
|
*
|
||||||
|
* @param uri the relative URI
|
||||||
|
* @return the song, or NULL if none was found
|
||||||
|
*/
|
||||||
|
gcc_pure
|
||||||
|
song *LookupSong(const char *uri);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a song object to this directory. Its "parent" attribute must
|
||||||
|
* be set already.
|
||||||
|
*/
|
||||||
|
void AddSong(song *song);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a song object from this directory (which effectively
|
||||||
|
* invalidates the song object, because the "parent" attribute becomes
|
||||||
|
* stale), but does not free it.
|
||||||
|
*/
|
||||||
|
void RemoveSong(song *song);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caller must lock the #db_mutex.
|
||||||
|
*/
|
||||||
|
void PruneEmpty();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort all directory entries recursively.
|
||||||
|
*
|
||||||
|
* Caller must lock the #db_mutex.
|
||||||
|
*/
|
||||||
|
void Sort();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caller must lock #db_mutex.
|
* Caller must lock #db_mutex.
|
||||||
*/
|
*/
|
||||||
@ -105,161 +253,4 @@ isRootDirectory(const char *name)
|
|||||||
return name[0] == 0 || (name[0] == '/' && name[1] == 0);
|
return name[0] == 0 || (name[0] == '/' && name[1] == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generic constructor for #directory object.
|
|
||||||
*/
|
|
||||||
gcc_malloc
|
|
||||||
struct directory *
|
|
||||||
directory_new(const char *dirname, struct directory *parent);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new root #directory object.
|
|
||||||
*/
|
|
||||||
gcc_malloc
|
|
||||||
static inline struct directory *
|
|
||||||
directory_new_root(void)
|
|
||||||
{
|
|
||||||
return directory_new("", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Free this #directory object (and the whole object tree within it),
|
|
||||||
* assuming it was already removed from the parent.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
directory_free(struct directory *directory);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove this #directory object from its parent and free it. This
|
|
||||||
* must not be called with the root directory.
|
|
||||||
*
|
|
||||||
* Caller must lock the #db_mutex.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
directory_delete(struct directory *directory);
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
directory_is_empty(const struct directory *directory)
|
|
||||||
{
|
|
||||||
return list_empty(&directory->children) &&
|
|
||||||
list_empty(&directory->songs) &&
|
|
||||||
list_empty(&directory->playlists);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const char *
|
|
||||||
directory_get_path(const struct directory *directory)
|
|
||||||
{
|
|
||||||
return directory->path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Is this the root directory of the music database?
|
|
||||||
*/
|
|
||||||
static inline bool
|
|
||||||
directory_is_root(const struct directory *directory)
|
|
||||||
{
|
|
||||||
return directory->parent == NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the base name of the directory.
|
|
||||||
*/
|
|
||||||
gcc_pure
|
|
||||||
const char *
|
|
||||||
directory_get_name(const struct directory *directory);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Caller must lock the #db_mutex.
|
|
||||||
*/
|
|
||||||
gcc_pure
|
|
||||||
struct directory *
|
|
||||||
directory_get_child(const struct directory *directory, const char *name);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new #directory object as a child of the given one.
|
|
||||||
*
|
|
||||||
* Caller must lock the #db_mutex.
|
|
||||||
*
|
|
||||||
* @param parent the parent directory the new one will be added to
|
|
||||||
* @param name_utf8 the UTF-8 encoded name of the new sub directory
|
|
||||||
*/
|
|
||||||
gcc_malloc
|
|
||||||
struct directory *
|
|
||||||
directory_new_child(struct directory *parent, const char *name_utf8);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Look up a sub directory, and create the object if it does not
|
|
||||||
* exist.
|
|
||||||
*
|
|
||||||
* Caller must lock the #db_mutex.
|
|
||||||
*/
|
|
||||||
static inline struct directory *
|
|
||||||
directory_make_child(struct directory *directory, const char *name_utf8)
|
|
||||||
{
|
|
||||||
struct directory *child = directory_get_child(directory, name_utf8);
|
|
||||||
if (child == NULL)
|
|
||||||
child = directory_new_child(directory, name_utf8);
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Caller must lock the #db_mutex.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
directory_prune_empty(struct directory *directory);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Looks up a directory by its relative URI.
|
|
||||||
*
|
|
||||||
* @param directory the parent (or grandparent, ...) directory
|
|
||||||
* @param uri the relative URI
|
|
||||||
* @return the directory, or NULL if none was found
|
|
||||||
*/
|
|
||||||
struct directory *
|
|
||||||
directory_lookup_directory(struct directory *directory, const char *uri);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a song object to this directory. Its "parent" attribute must
|
|
||||||
* be set already.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
directory_add_song(struct directory *directory, struct song *song);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove a song object from this directory (which effectively
|
|
||||||
* invalidates the song object, because the "parent" attribute becomes
|
|
||||||
* stale), but does not free it.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
directory_remove_song(struct directory *directory, struct song *song);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Look up a song in this directory by its name.
|
|
||||||
*
|
|
||||||
* Caller must lock the #db_mutex.
|
|
||||||
*/
|
|
||||||
gcc_pure
|
|
||||||
struct song *
|
|
||||||
directory_get_song(const struct directory *directory, const char *name_utf8);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Looks up a song by its relative URI.
|
|
||||||
*
|
|
||||||
* Caller must lock the #db_mutex.
|
|
||||||
*
|
|
||||||
* @param directory the parent (or grandparent, ...) directory
|
|
||||||
* @param uri the relative URI
|
|
||||||
* @return the song, or NULL if none was found
|
|
||||||
*/
|
|
||||||
struct song *
|
|
||||||
directory_lookup_song(struct directory *directory, const char *uri);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sort all directory entries recursively.
|
|
||||||
*
|
|
||||||
* Caller must lock the #db_mutex.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
directory_sort(struct directory *directory);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,12 +48,11 @@ directory_quark(void)
|
|||||||
void
|
void
|
||||||
directory_save(FILE *fp, const struct directory *directory)
|
directory_save(FILE *fp, const struct directory *directory)
|
||||||
{
|
{
|
||||||
if (!directory_is_root(directory)) {
|
if (!directory->IsRoot()) {
|
||||||
fprintf(fp, DIRECTORY_MTIME "%lu\n",
|
fprintf(fp, DIRECTORY_MTIME "%lu\n",
|
||||||
(unsigned long)directory->mtime);
|
(unsigned long)directory->mtime);
|
||||||
|
|
||||||
fprintf(fp, "%s%s\n", DIRECTORY_BEGIN,
|
fprintf(fp, "%s%s\n", DIRECTORY_BEGIN, directory->GetPath());
|
||||||
directory_get_path(directory));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct directory *cur;
|
struct directory *cur;
|
||||||
@ -75,9 +74,8 @@ directory_save(FILE *fp, const struct directory *directory)
|
|||||||
|
|
||||||
playlist_vector_save(fp, &directory->playlists);
|
playlist_vector_save(fp, &directory->playlists);
|
||||||
|
|
||||||
if (!directory_is_root(directory))
|
if (!directory->IsRoot())
|
||||||
fprintf(fp, DIRECTORY_END "%s\n",
|
fprintf(fp, DIRECTORY_END "%s\n", directory->GetPath());
|
||||||
directory_get_path(directory));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct directory *
|
static struct directory *
|
||||||
@ -87,19 +85,19 @@ directory_load_subdir(FILE *fp, struct directory *parent, const char *name,
|
|||||||
const char *line;
|
const char *line;
|
||||||
bool success;
|
bool success;
|
||||||
|
|
||||||
if (directory_get_child(parent, name) != NULL) {
|
if (parent->FindChild(name) != nullptr) {
|
||||||
g_set_error(error_r, directory_quark(), 0,
|
g_set_error(error_r, directory_quark(), 0,
|
||||||
"Duplicate subdirectory '%s'", name);
|
"Duplicate subdirectory '%s'", name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct directory *directory = directory_new_child(parent, name);
|
struct directory *directory = parent->CreateChild(name);
|
||||||
|
|
||||||
line = read_text_line(fp, buffer);
|
line = read_text_line(fp, buffer);
|
||||||
if (line == NULL) {
|
if (line == NULL) {
|
||||||
g_set_error(error_r, directory_quark(), 0,
|
g_set_error(error_r, directory_quark(), 0,
|
||||||
"Unexpected end of file");
|
"Unexpected end of file");
|
||||||
directory_delete(directory);
|
directory->Delete();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +110,7 @@ directory_load_subdir(FILE *fp, struct directory *parent, const char *name,
|
|||||||
if (line == NULL) {
|
if (line == NULL) {
|
||||||
g_set_error(error_r, directory_quark(), 0,
|
g_set_error(error_r, directory_quark(), 0,
|
||||||
"Unexpected end of file");
|
"Unexpected end of file");
|
||||||
directory_delete(directory);
|
directory->Delete();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,13 +118,13 @@ directory_load_subdir(FILE *fp, struct directory *parent, const char *name,
|
|||||||
if (!g_str_has_prefix(line, DIRECTORY_BEGIN)) {
|
if (!g_str_has_prefix(line, DIRECTORY_BEGIN)) {
|
||||||
g_set_error(error_r, directory_quark(), 0,
|
g_set_error(error_r, directory_quark(), 0,
|
||||||
"Malformed line: %s", line);
|
"Malformed line: %s", line);
|
||||||
directory_delete(directory);
|
directory->Delete();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
success = directory_load(fp, directory, buffer, error_r);
|
success = directory_load(fp, directory, buffer, error_r);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
directory_delete(directory);
|
directory->Delete();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +150,7 @@ directory_load(FILE *fp, struct directory *directory,
|
|||||||
const char *name = line + sizeof(SONG_BEGIN) - 1;
|
const char *name = line + sizeof(SONG_BEGIN) - 1;
|
||||||
struct song *song;
|
struct song *song;
|
||||||
|
|
||||||
if (directory_get_song(directory, name) != NULL) {
|
if (directory->FindSong(name) != nullptr) {
|
||||||
g_set_error(error, directory_quark(), 0,
|
g_set_error(error, directory_quark(), 0,
|
||||||
"Duplicate song '%s'", name);
|
"Duplicate song '%s'", name);
|
||||||
return false;
|
return false;
|
||||||
@ -163,7 +161,7 @@ directory_load(FILE *fp, struct directory *directory,
|
|||||||
if (song == NULL)
|
if (song == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
directory_add_song(directory, song);
|
directory->AddSong(song);
|
||||||
} else if (g_str_has_prefix(line, PLAYLIST_META_BEGIN)) {
|
} else if (g_str_has_prefix(line, PLAYLIST_META_BEGIN)) {
|
||||||
/* duplicate the name, because
|
/* duplicate the name, because
|
||||||
playlist_metadata_load() will overwrite the
|
playlist_metadata_load() will overwrite the
|
||||||
|
@ -186,10 +186,10 @@ map_directory_fs(const struct directory *directory)
|
|||||||
assert(music_dir_utf8 != NULL);
|
assert(music_dir_utf8 != NULL);
|
||||||
assert(music_dir_fs != NULL);
|
assert(music_dir_fs != NULL);
|
||||||
|
|
||||||
if (directory_is_root(directory))
|
if (directory->IsRoot())
|
||||||
return g_strdup(music_dir_fs);
|
return g_strdup(music_dir_fs);
|
||||||
|
|
||||||
return map_uri_fs(directory_get_path(directory));
|
return map_uri_fs(directory->GetPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
|
@ -161,10 +161,10 @@ song_get_uri(const struct song *song)
|
|||||||
assert(song != nullptr);
|
assert(song != nullptr);
|
||||||
assert(*song->uri);
|
assert(*song->uri);
|
||||||
|
|
||||||
if (!song_in_database(song) || directory_is_root(song->parent))
|
if (!song_in_database(song) || song->parent->IsRoot())
|
||||||
return g_strdup(song->uri);
|
return g_strdup(song->uri);
|
||||||
else
|
else
|
||||||
return g_strconcat(directory_get_path(song->parent),
|
return g_strconcat(song->parent->GetPath(),
|
||||||
"/", song->uri, nullptr);
|
"/", song->uri, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,9 +33,9 @@ extern "C" {
|
|||||||
void
|
void
|
||||||
song_print_uri(struct client *client, struct song *song)
|
song_print_uri(struct client *client, struct song *song)
|
||||||
{
|
{
|
||||||
if (song_in_database(song) && !directory_is_root(song->parent)) {
|
if (song_in_database(song) && !song->parent->IsRoot()) {
|
||||||
client_printf(client, "%s%s/%s\n", SONG_FILE,
|
client_printf(client, "%s%s/%s\n", SONG_FILE,
|
||||||
directory_get_path(song->parent), song->uri);
|
song->parent->GetPath(), song->uri);
|
||||||
} else {
|
} else {
|
||||||
char *allocated;
|
char *allocated;
|
||||||
const char *uri;
|
const char *uri;
|
||||||
|
@ -123,14 +123,12 @@ sticker_song_find_cb(const char *uri, const char *value, gpointer user_data)
|
|||||||
{
|
{
|
||||||
struct sticker_song_find_data *data =
|
struct sticker_song_find_data *data =
|
||||||
(struct sticker_song_find_data *)user_data;
|
(struct sticker_song_find_data *)user_data;
|
||||||
struct song *song;
|
|
||||||
|
|
||||||
if (memcmp(uri, data->base_uri, data->base_uri_length) != 0)
|
if (memcmp(uri, data->base_uri, data->base_uri_length) != 0)
|
||||||
/* should not happen, ignore silently */
|
/* should not happen, ignore silently */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
song = directory_lookup_song(data->directory,
|
song *song = data->directory->LookupSong(uri + data->base_uri_length);
|
||||||
uri + data->base_uri_length);
|
|
||||||
if (song != NULL)
|
if (song != NULL)
|
||||||
data->func(song, value, data->user_data);
|
data->func(song, value, data->user_data);
|
||||||
}
|
}
|
||||||
@ -147,7 +145,7 @@ sticker_song_find(struct directory *directory, const char *name,
|
|||||||
data.user_data = user_data;
|
data.user_data = user_data;
|
||||||
|
|
||||||
char *allocated;
|
char *allocated;
|
||||||
data.base_uri = directory_get_path(directory);
|
data.base_uri = directory->GetPath();
|
||||||
if (*data.base_uri != 0)
|
if (*data.base_uri != 0)
|
||||||
/* append slash to base_uri */
|
/* append slash to base_uri */
|
||||||
data.base_uri = allocated =
|
data.base_uri = allocated =
|
||||||
|
@ -43,7 +43,7 @@ update_archive_tree(struct directory *directory, char *name)
|
|||||||
//add dir is not there already
|
//add dir is not there already
|
||||||
db_lock();
|
db_lock();
|
||||||
struct directory *subdir =
|
struct directory *subdir =
|
||||||
directory_make_child(directory, name);
|
directory->MakeChild(name);
|
||||||
subdir->device = DEVICE_INARCHIVE;
|
subdir->device = DEVICE_INARCHIVE;
|
||||||
db_unlock();
|
db_unlock();
|
||||||
//create directories first
|
//create directories first
|
||||||
@ -56,18 +56,18 @@ update_archive_tree(struct directory *directory, char *name)
|
|||||||
|
|
||||||
//add file
|
//add file
|
||||||
db_lock();
|
db_lock();
|
||||||
struct song *song = directory_get_song(directory, name);
|
struct song *song = directory->FindSong(name);
|
||||||
db_unlock();
|
db_unlock();
|
||||||
if (song == NULL) {
|
if (song == NULL) {
|
||||||
song = song_file_load(name, directory);
|
song = song_file_load(name, directory);
|
||||||
if (song != NULL) {
|
if (song != NULL) {
|
||||||
db_lock();
|
db_lock();
|
||||||
directory_add_song(directory, song);
|
directory->AddSong(song);
|
||||||
db_unlock();
|
db_unlock();
|
||||||
|
|
||||||
modified = true;
|
modified = true;
|
||||||
g_message("added %s/%s",
|
g_message("added %s/%s",
|
||||||
directory_get_path(directory), name);
|
directory->GetPath(), name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,7 +87,7 @@ update_archive_file2(struct directory *parent, const char *name,
|
|||||||
const struct archive_plugin *plugin)
|
const struct archive_plugin *plugin)
|
||||||
{
|
{
|
||||||
db_lock();
|
db_lock();
|
||||||
struct directory *directory = directory_get_child(parent, name);
|
directory *directory = parent->FindChild(name);
|
||||||
db_unlock();
|
db_unlock();
|
||||||
|
|
||||||
if (directory != NULL && directory->mtime == st->st_mtime &&
|
if (directory != NULL && directory->mtime == st->st_mtime &&
|
||||||
@ -114,7 +114,7 @@ update_archive_file2(struct directory *parent, const char *name,
|
|||||||
if (directory == NULL) {
|
if (directory == NULL) {
|
||||||
g_debug("creating archive directory: %s", name);
|
g_debug("creating archive directory: %s", name);
|
||||||
db_lock();
|
db_lock();
|
||||||
directory = directory_new_child(parent, name);
|
directory = parent->CreateChild(name);
|
||||||
/* mark this directory as archive (we use device for
|
/* mark this directory as archive (we use device for
|
||||||
this) */
|
this) */
|
||||||
directory->device = DEVICE_INARCHIVE;
|
directory->device = DEVICE_INARCHIVE;
|
||||||
|
@ -46,7 +46,7 @@ static struct directory *
|
|||||||
make_directory_if_modified(struct directory *parent, const char *name,
|
make_directory_if_modified(struct directory *parent, const char *name,
|
||||||
const struct stat *st)
|
const struct stat *st)
|
||||||
{
|
{
|
||||||
struct directory *directory = directory_get_child(parent, name);
|
directory *directory = parent->FindChild(name);
|
||||||
|
|
||||||
// directory exists already
|
// directory exists already
|
||||||
if (directory != NULL) {
|
if (directory != NULL) {
|
||||||
@ -60,7 +60,7 @@ make_directory_if_modified(struct directory *parent, const char *name,
|
|||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
directory = directory_make_child(parent, name);
|
directory = parent->MakeChild(name);
|
||||||
directory->mtime = st->st_mtime;
|
directory->mtime = st->st_mtime;
|
||||||
return directory;
|
return directory;
|
||||||
}
|
}
|
||||||
@ -104,13 +104,12 @@ update_container_file(struct directory *directory,
|
|||||||
g_free(child_path_fs);
|
g_free(child_path_fs);
|
||||||
|
|
||||||
db_lock();
|
db_lock();
|
||||||
directory_add_song(contdir, song);
|
contdir->AddSong(song);
|
||||||
db_unlock();
|
db_unlock();
|
||||||
|
|
||||||
modified = true;
|
modified = true;
|
||||||
|
|
||||||
g_message("added %s/%s",
|
g_message("added %s/%s", directory->GetPath(), vtrack);
|
||||||
directory_get_path(directory), vtrack);
|
|
||||||
g_free(vtrack);
|
g_free(vtrack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ delete_song(struct directory *dir, struct song *del)
|
|||||||
assert(del->parent == dir);
|
assert(del->parent == dir);
|
||||||
|
|
||||||
/* first, prevent traversers in main task from getting this */
|
/* first, prevent traversers in main task from getting this */
|
||||||
directory_remove_song(dir, del);
|
dir->RemoveSong(del);
|
||||||
|
|
||||||
db_unlock(); /* temporary unlock, because update_remove_song() blocks */
|
db_unlock(); /* temporary unlock, because update_remove_song() blocks */
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ delete_directory(struct directory *directory)
|
|||||||
|
|
||||||
clear_directory(directory);
|
clear_directory(directory);
|
||||||
|
|
||||||
directory_delete(directory);
|
directory->Delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -83,14 +83,14 @@ delete_name_in(struct directory *parent, const char *name)
|
|||||||
bool modified = false;
|
bool modified = false;
|
||||||
|
|
||||||
db_lock();
|
db_lock();
|
||||||
struct directory *directory = directory_get_child(parent, name);
|
directory *directory = parent->FindChild(name);
|
||||||
|
|
||||||
if (directory != NULL) {
|
if (directory != NULL) {
|
||||||
delete_directory(directory);
|
delete_directory(directory);
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct song *song = directory_get_song(parent, name);
|
struct song *song = parent->FindSong(name);
|
||||||
if (song != NULL) {
|
if (song != NULL) {
|
||||||
delete_song(parent, song);
|
delete_song(parent, song);
|
||||||
modified = true;
|
modified = true;
|
||||||
|
@ -42,12 +42,12 @@ update_song_file2(struct directory *directory,
|
|||||||
const struct decoder_plugin *plugin)
|
const struct decoder_plugin *plugin)
|
||||||
{
|
{
|
||||||
db_lock();
|
db_lock();
|
||||||
struct song *song = directory_get_song(directory, name);
|
struct song *song = directory->FindSong(name);
|
||||||
db_unlock();
|
db_unlock();
|
||||||
|
|
||||||
if (!directory_child_access(directory, name, R_OK)) {
|
if (!directory_child_access(directory, name, R_OK)) {
|
||||||
g_warning("no read permissions on %s/%s",
|
g_warning("no read permissions on %s/%s",
|
||||||
directory_get_path(directory), name);
|
directory->GetPath(), name);
|
||||||
if (song != NULL) {
|
if (song != NULL) {
|
||||||
db_lock();
|
db_lock();
|
||||||
delete_song(directory, song);
|
delete_song(directory, song);
|
||||||
@ -70,28 +70,27 @@ update_song_file2(struct directory *directory,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (song == NULL) {
|
if (song == NULL) {
|
||||||
g_debug("reading %s/%s",
|
g_debug("reading %s/%s", directory->GetPath(), name);
|
||||||
directory_get_path(directory), name);
|
|
||||||
song = song_file_load(name, directory);
|
song = song_file_load(name, directory);
|
||||||
if (song == NULL) {
|
if (song == NULL) {
|
||||||
g_debug("ignoring unrecognized file %s/%s",
|
g_debug("ignoring unrecognized file %s/%s",
|
||||||
directory_get_path(directory), name);
|
directory->GetPath(), name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
db_lock();
|
db_lock();
|
||||||
directory_add_song(directory, song);
|
directory->AddSong(song);
|
||||||
db_unlock();
|
db_unlock();
|
||||||
|
|
||||||
modified = true;
|
modified = true;
|
||||||
g_message("added %s/%s",
|
g_message("added %s/%s",
|
||||||
directory_get_path(directory), name);
|
directory->GetPath(), name);
|
||||||
} else if (st->st_mtime != song->mtime || walk_discard) {
|
} else if (st->st_mtime != song->mtime || walk_discard) {
|
||||||
g_message("updating %s/%s",
|
g_message("updating %s/%s",
|
||||||
directory_get_path(directory), name);
|
directory->GetPath(), name);
|
||||||
if (!song_file_update(song)) {
|
if (!song_file_update(song)) {
|
||||||
g_debug("deleting unrecognized file %s/%s",
|
g_debug("deleting unrecognized file %s/%s",
|
||||||
directory_get_path(directory), name);
|
directory->GetPath(), name);
|
||||||
db_lock();
|
db_lock();
|
||||||
delete_song(directory, song);
|
delete_song(directory, song);
|
||||||
db_unlock();
|
db_unlock();
|
||||||
|
@ -102,7 +102,7 @@ remove_excluded_from_directory(struct directory *directory,
|
|||||||
|
|
||||||
struct directory *child, *n;
|
struct directory *child, *n;
|
||||||
directory_for_each_child_safe(child, n, directory) {
|
directory_for_each_child_safe(child, n, directory) {
|
||||||
char *name_fs = utf8_to_fs_charset(directory_get_name(child));
|
char *name_fs = utf8_to_fs_charset(child->GetName());
|
||||||
|
|
||||||
if (exclude_list_check(exclude_list, name_fs)) {
|
if (exclude_list_check(exclude_list, name_fs)) {
|
||||||
delete_directory(child);
|
delete_directory(child);
|
||||||
@ -254,8 +254,7 @@ update_directory_child(struct directory *directory,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
db_lock();
|
db_lock();
|
||||||
struct directory *subdir =
|
struct directory *subdir = directory->MakeChild(name);
|
||||||
directory_make_child(directory, name);
|
|
||||||
db_unlock();
|
db_unlock();
|
||||||
|
|
||||||
assert(directory == subdir->parent);
|
assert(directory == subdir->parent);
|
||||||
@ -423,7 +422,7 @@ static struct directory *
|
|||||||
directory_make_child_checked(struct directory *parent, const char *name_utf8)
|
directory_make_child_checked(struct directory *parent, const char *name_utf8)
|
||||||
{
|
{
|
||||||
db_lock();
|
db_lock();
|
||||||
struct directory *directory = directory_get_child(parent, name_utf8);
|
directory *directory = parent->FindChild(name_utf8);
|
||||||
db_unlock();
|
db_unlock();
|
||||||
|
|
||||||
if (directory != NULL)
|
if (directory != NULL)
|
||||||
@ -440,11 +439,11 @@ directory_make_child_checked(struct directory *parent, const char *name_utf8)
|
|||||||
/* if we're adding directory paths, make sure to delete filenames
|
/* if we're adding directory paths, make sure to delete filenames
|
||||||
with potentially the same name */
|
with potentially the same name */
|
||||||
db_lock();
|
db_lock();
|
||||||
struct song *conflicting = directory_get_song(parent, name_utf8);
|
struct song *conflicting = parent->FindSong(name_utf8);
|
||||||
if (conflicting)
|
if (conflicting)
|
||||||
delete_song(parent, conflicting);
|
delete_song(parent, conflicting);
|
||||||
|
|
||||||
directory = directory_new_child(parent, name_utf8);
|
directory = parent->CreateChild(name_utf8);
|
||||||
db_unlock();
|
db_unlock();
|
||||||
|
|
||||||
directory_set_stat(directory, &st);
|
directory_set_stat(directory, &st);
|
||||||
|
@ -168,7 +168,7 @@ ProxyDatabase::Open(GError **error_r)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
root = directory_new_root();
|
root = directory::NewRoot();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -178,7 +178,7 @@ ProxyDatabase::Close()
|
|||||||
{
|
{
|
||||||
assert(connection != nullptr);
|
assert(connection != nullptr);
|
||||||
|
|
||||||
directory_free(root);
|
root->Free();
|
||||||
mpd_connection_free(connection);
|
mpd_connection_free(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,9 +241,9 @@ Visit(struct mpd_connection *connection,
|
|||||||
|
|
||||||
if (visit_directory) {
|
if (visit_directory) {
|
||||||
struct directory *d =
|
struct directory *d =
|
||||||
directory_new(path, &detached_root);
|
directory::NewGeneric(path, &detached_root);
|
||||||
bool success = visit_directory(*d, error_r);
|
bool success = visit_directory(*d, error_r);
|
||||||
directory_free(d);
|
d->Free();
|
||||||
if (!success)
|
if (!success)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ SimpleDatabase::Load(GError **error_r)
|
|||||||
bool
|
bool
|
||||||
SimpleDatabase::Open(GError **error_r)
|
SimpleDatabase::Open(GError **error_r)
|
||||||
{
|
{
|
||||||
root = directory_new_root();
|
root = directory::NewRoot();
|
||||||
mtime = 0;
|
mtime = 0;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@ -189,7 +189,7 @@ SimpleDatabase::Open(GError **error_r)
|
|||||||
|
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
if (!Load(&error)) {
|
if (!Load(&error)) {
|
||||||
directory_free(root);
|
root->Free();
|
||||||
|
|
||||||
g_warning("Failed to load database: %s", error->message);
|
g_warning("Failed to load database: %s", error->message);
|
||||||
g_error_free(error);
|
g_error_free(error);
|
||||||
@ -197,7 +197,7 @@ SimpleDatabase::Open(GError **error_r)
|
|||||||
if (!Check(error_r))
|
if (!Check(error_r))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
root = directory_new_root();
|
root = directory::NewRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -209,7 +209,7 @@ SimpleDatabase::Close()
|
|||||||
assert(root != NULL);
|
assert(root != NULL);
|
||||||
assert(borrowed_song_count == 0);
|
assert(borrowed_song_count == 0);
|
||||||
|
|
||||||
directory_free(root);
|
root->Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct song *
|
struct song *
|
||||||
@ -218,7 +218,7 @@ SimpleDatabase::GetSong(const char *uri, GError **error_r) const
|
|||||||
assert(root != NULL);
|
assert(root != NULL);
|
||||||
|
|
||||||
db_lock();
|
db_lock();
|
||||||
struct song *song = directory_lookup_song(root, uri);
|
song *song = root->LookupSong(uri);
|
||||||
db_unlock();
|
db_unlock();
|
||||||
if (song == NULL)
|
if (song == NULL)
|
||||||
g_set_error(error_r, db_quark(), DB_NOT_FOUND,
|
g_set_error(error_r, db_quark(), DB_NOT_FOUND,
|
||||||
@ -250,7 +250,7 @@ SimpleDatabase::LookupDirectory(const char *uri) const
|
|||||||
assert(uri != NULL);
|
assert(uri != NULL);
|
||||||
|
|
||||||
ScopeDatabaseLock protect;
|
ScopeDatabaseLock protect;
|
||||||
return directory_lookup_directory(root, uri);
|
return root->LookupDirectory(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -262,12 +262,10 @@ SimpleDatabase::Visit(const DatabaseSelection &selection,
|
|||||||
{
|
{
|
||||||
ScopeDatabaseLock protect;
|
ScopeDatabaseLock protect;
|
||||||
|
|
||||||
const struct directory *directory =
|
const directory *directory = root->LookupDirectory(selection.uri);
|
||||||
directory_lookup_directory(root, selection.uri);
|
|
||||||
if (directory == NULL) {
|
if (directory == NULL) {
|
||||||
if (visit_song) {
|
if (visit_song) {
|
||||||
struct song *song =
|
song *song = root->LookupSong(selection.uri);
|
||||||
directory_lookup_song(root, selection.uri);
|
|
||||||
if (song != nullptr)
|
if (song != nullptr)
|
||||||
return !selection.Match(*song) ||
|
return !selection.Match(*song) ||
|
||||||
visit_song(*song, error_r);
|
visit_song(*song, error_r);
|
||||||
@ -310,10 +308,10 @@ SimpleDatabase::Save(GError **error_r)
|
|||||||
db_lock();
|
db_lock();
|
||||||
|
|
||||||
g_debug("removing empty directories from DB");
|
g_debug("removing empty directories from DB");
|
||||||
directory_prune_empty(root);
|
root->PruneEmpty();
|
||||||
|
|
||||||
g_debug("sorting DB");
|
g_debug("sorting DB");
|
||||||
directory_sort(root);
|
root->Sort();
|
||||||
|
|
||||||
db_unlock();
|
db_unlock();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user