You need to sign in or sign up before continuing.
Commit 0eb05b82 authored by Max Kellermann's avatar Max Kellermann

Directory: turn functions to methods

parent 0c245bc2
...@@ -128,9 +128,7 @@ db_get_directory(const char *name) ...@@ -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" { ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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
......
...@@ -91,175 +91,166 @@ struct directory { ...@@ -91,175 +91,166 @@ struct directory {
char path[sizeof(long)]; char path[sizeof(long)];
/** /**
* Caller must lock #db_mutex. * Generic constructor for #directory object.
*/ */
bool Walk(bool recursive, const SongFilter *match, gcc_malloc
VisitDirectory visit_directory, VisitSong visit_song, static directory *NewGeneric(const char *path_utf8, directory *parent);
VisitPlaylist visit_playlist,
GError **error_r) const;
};
static inline bool /**
isRootDirectory(const char *name) * Create a new root #directory object.
{ */
return name[0] == 0 || (name[0] == '/' && name[1] == 0); gcc_malloc
} static directory *NewRoot() {
return NewGeneric("", nullptr);
}
/** /**
* Generic constructor for #directory object. * Free this #directory object (and the whole object tree within it),
*/ * assuming it was already removed from the parent.
gcc_malloc */
struct directory * void Free();
directory_new(const char *dirname, struct directory *parent);
/** /**
* Create a new root #directory object. * Remove this #directory object from its parent and free it. This
*/ * must not be called with the root directory.
gcc_malloc *
static inline struct directory * * Caller must lock the #db_mutex.
directory_new_root(void) */
{ void Delete();
return directory_new("", NULL);
}
/** /**
* Free this #directory object (and the whole object tree within it), * Create a new #directory object as a child of the given one.
* assuming it was already removed from the parent. *
*/ * Caller must lock the #db_mutex.
void *
directory_free(struct directory *directory); * @param name_utf8 the UTF-8 encoded name of the new sub directory
*/
gcc_malloc
directory *CreateChild(const char *name_utf8);
/** /**
* Remove this #directory object from its parent and free it. This * Caller must lock the #db_mutex.
* must not be called with the root directory. */
* gcc_pure
* Caller must lock the #db_mutex. const directory *FindChild(const char *name) const;
*/
void
directory_delete(struct directory *directory);
static inline bool gcc_pure
directory_is_empty(const struct directory *directory) directory *FindChild(const char *name) {
{ const directory *cthis = this;
return list_empty(&directory->children) && return const_cast<directory *>(cthis->FindChild(name));
list_empty(&directory->songs) && }
list_empty(&directory->playlists);
}
static inline const char * /**
directory_get_path(const struct directory *directory) * Look up a sub directory, and create the object if it does not
{ * exist.
return directory->path; *
} * 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;
}
/** /**
* Is this the root directory of the music database? * Looks up a directory by its relative URI.
*/ *
static inline bool * @param uri the relative URI
directory_is_root(const struct directory *directory) * @return the directory, or NULL if none was found
{ */
return directory->parent == NULL; gcc_pure
} directory *LookupDirectory(const char *uri);
/** gcc_pure
* Returns the base name of the directory. bool IsEmpty() const {
*/ return list_empty(&children) &&
gcc_pure list_empty(&songs) &&
const char * list_empty(&playlists);
directory_get_name(const struct directory *directory); }
/** gcc_pure
* Caller must lock the #db_mutex. const char *GetPath() const {
*/ return path;
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. * Returns the base name of the directory.
* */
* Caller must lock the #db_mutex. gcc_pure
* const char *GetName() const;
* @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 * Is this the root directory of the music database?
* exist. */
* gcc_pure
* Caller must lock the #db_mutex. bool IsRoot() const {
*/ return parent == NULL;
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. * Look up a song in this directory by its name.
*/ *
void * Caller must lock the #db_mutex.
directory_prune_empty(struct directory *directory); */
gcc_pure
const song *FindSong(const char *name_utf8) const;
/** gcc_pure
* Looks up a directory by its relative URI. song *FindSong(const char *name_utf8) {
* const directory *cthis = this;
* @param directory the parent (or grandparent, ...) directory return const_cast<song *>(cthis->FindSong(name_utf8));
* @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 * Looks up a song by its relative URI.
* be set already. *
*/ * Caller must lock the #db_mutex.
void *
directory_add_song(struct directory *directory, struct song *song); * @param uri the relative URI
* @return the song, or NULL if none was found
*/
gcc_pure
song *LookupSong(const char *uri);
/** /**
* Remove a song object from this directory (which effectively * Add a song object to this directory. Its "parent" attribute must
* invalidates the song object, because the "parent" attribute becomes * be set already.
* stale), but does not free it. */
*/ void AddSong(song *song);
void
directory_remove_song(struct directory *directory, struct song *song);
/** /**
* Look up a song in this directory by its name. * Remove a song object from this directory (which effectively
* * invalidates the song object, because the "parent" attribute becomes
* Caller must lock the #db_mutex. * stale), but does not free it.
*/ */
gcc_pure void RemoveSong(song *song);
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.
* */
* Caller must lock the #db_mutex. void PruneEmpty();
*
* @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. * Sort all directory entries recursively.
* *
* Caller must lock the #db_mutex. * Caller must lock the #db_mutex.
*/ */
void void Sort();
directory_sort(struct directory *directory);
/**
* Caller must lock #db_mutex.
*/
bool Walk(bool recursive, const SongFilter *match,
VisitDirectory visit_directory, VisitSong visit_song,
VisitPlaylist visit_playlist,
GError **error_r) const;
};
static inline bool
isRootDirectory(const char *name)
{
return name[0] == 0 || (name[0] == '/' && name[1] == 0);
}
#endif #endif
...@@ -48,12 +48,11 @@ directory_quark(void) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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" { ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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 * ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 * ...@@ -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) ...@@ -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) ...@@ -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() ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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() ...@@ -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 ...@@ -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 ...@@ -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, ...@@ -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) ...@@ -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();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment