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)
|
||||
return music_root;
|
||||
|
||||
struct directory *directory =
|
||||
directory_lookup_directory(music_root, name);
|
||||
return directory;
|
||||
return music_root->LookupDirectory(name);
|
||||
}
|
||||
|
||||
struct song *
|
||||
|
@ -41,9 +41,8 @@ extern "C" {
|
||||
static bool
|
||||
PrintDirectory(struct client *client, const directory &directory)
|
||||
{
|
||||
if (!directory_is_root(&directory))
|
||||
client_printf(client, "directory: %s\n",
|
||||
directory_get_path(&directory));
|
||||
if (!directory.IsRoot())
|
||||
client_printf(client, "directory: %s\n", directory.GetPath());
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -53,11 +52,11 @@ print_playlist_in_directory(struct client *client,
|
||||
const directory &directory,
|
||||
const char *name_utf8)
|
||||
{
|
||||
if (directory_is_root(&directory))
|
||||
if (directory.IsRoot())
|
||||
client_printf(client, "playlist: %s\n", name_utf8);
|
||||
else
|
||||
client_printf(client, "playlist: %s/%s\n",
|
||||
directory_get_path(&directory), name_utf8);
|
||||
directory.GetPath(), name_utf8);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -56,7 +56,7 @@ directory_allocate(const char *path)
|
||||
}
|
||||
|
||||
struct directory *
|
||||
directory_new(const char *path, struct directory *parent)
|
||||
directory::NewGeneric(const char *path, struct directory *parent)
|
||||
{
|
||||
assert(path != NULL);
|
||||
assert((*path == 0) == (parent == NULL));
|
||||
@ -69,124 +69,121 @@ directory_new(const char *path, struct directory *parent)
|
||||
}
|
||||
|
||||
void
|
||||
directory_free(struct directory *directory)
|
||||
directory::Free()
|
||||
{
|
||||
playlist_vector_deinit(&directory->playlists);
|
||||
playlist_vector_deinit(&playlists);
|
||||
|
||||
struct song *song, *ns;
|
||||
directory_for_each_song_safe(song, ns, directory)
|
||||
directory_for_each_song_safe(song, ns, this)
|
||||
song_free(song);
|
||||
|
||||
struct directory *child, *n;
|
||||
directory_for_each_child_safe(child, n, directory)
|
||||
directory_free(child);
|
||||
directory_for_each_child_safe(child, n, this)
|
||||
child->Free();
|
||||
|
||||
g_free(directory);
|
||||
/* this resets last dir returned */
|
||||
/*directory_get_path(NULL); */
|
||||
g_free(this);
|
||||
}
|
||||
|
||||
void
|
||||
directory_delete(struct directory *directory)
|
||||
directory::Delete()
|
||||
{
|
||||
assert(holding_db_lock());
|
||||
assert(directory != NULL);
|
||||
assert(directory->parent != NULL);
|
||||
assert(parent != nullptr);
|
||||
|
||||
list_del(&directory->siblings);
|
||||
directory_free(directory);
|
||||
list_del(&siblings);
|
||||
Free();
|
||||
}
|
||||
|
||||
const char *
|
||||
directory_get_name(const struct directory *directory)
|
||||
directory::GetName() const
|
||||
{
|
||||
assert(!directory_is_root(directory));
|
||||
assert(directory->path != NULL);
|
||||
assert(!IsRoot());
|
||||
assert(path != nullptr);
|
||||
|
||||
const char *slash = strrchr(directory->path, '/');
|
||||
assert((slash == NULL) == directory_is_root(directory->parent));
|
||||
const char *slash = strrchr(path, '/');
|
||||
assert((slash == nullptr) == parent->IsRoot());
|
||||
|
||||
return slash != NULL
|
||||
? slash + 1
|
||||
: directory->path;
|
||||
: path;
|
||||
}
|
||||
|
||||
struct directory *
|
||||
directory_new_child(struct directory *parent, const char *name_utf8)
|
||||
directory::CreateChild(const char *name_utf8)
|
||||
{
|
||||
assert(holding_db_lock());
|
||||
assert(parent != NULL);
|
||||
assert(name_utf8 != NULL);
|
||||
assert(*name_utf8 != 0);
|
||||
|
||||
char *allocated;
|
||||
const char *path_utf8;
|
||||
if (directory_is_root(parent)) {
|
||||
if (IsRoot()) {
|
||||
allocated = NULL;
|
||||
path_utf8 = name_utf8;
|
||||
} else {
|
||||
allocated = g_strconcat(directory_get_path(parent),
|
||||
allocated = g_strconcat(GetPath(),
|
||||
"/", name_utf8, NULL);
|
||||
path_utf8 = allocated;
|
||||
}
|
||||
|
||||
struct directory *directory = directory_new(path_utf8, parent);
|
||||
directory *child = NewGeneric(path_utf8, this);
|
||||
g_free(allocated);
|
||||
|
||||
list_add_tail(&directory->siblings, &parent->children);
|
||||
return directory;
|
||||
list_add_tail(&child->siblings, &children);
|
||||
return child;
|
||||
}
|
||||
|
||||
struct directory *
|
||||
directory_get_child(const struct directory *directory, const char *name)
|
||||
const directory *
|
||||
directory::FindChild(const char *name) const
|
||||
{
|
||||
assert(holding_db_lock());
|
||||
|
||||
struct directory *child;
|
||||
directory_for_each_child(child, directory)
|
||||
if (strcmp(directory_get_name(child), name) == 0)
|
||||
const struct directory *child;
|
||||
directory_for_each_child(child, this)
|
||||
if (strcmp(child->GetName(), name) == 0)
|
||||
return child;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
directory_prune_empty(struct directory *directory)
|
||||
directory::PruneEmpty()
|
||||
{
|
||||
assert(holding_db_lock());
|
||||
|
||||
struct directory *child, *n;
|
||||
directory_for_each_child_safe(child, n, directory) {
|
||||
directory_prune_empty(child);
|
||||
directory_for_each_child_safe(child, n, this) {
|
||||
child->PruneEmpty();
|
||||
|
||||
if (directory_is_empty(child))
|
||||
directory_delete(child);
|
||||
if (child->IsEmpty())
|
||||
child->Delete();
|
||||
}
|
||||
}
|
||||
|
||||
struct directory *
|
||||
directory_lookup_directory(struct directory *directory, const char *uri)
|
||||
directory::LookupDirectory(const char *uri)
|
||||
{
|
||||
assert(holding_db_lock());
|
||||
assert(uri != NULL);
|
||||
|
||||
if (isRootDirectory(uri))
|
||||
return directory;
|
||||
return this;
|
||||
|
||||
char *duplicated = g_strdup(uri), *name = duplicated;
|
||||
|
||||
struct directory *d = this;
|
||||
while (1) {
|
||||
char *slash = strchr(name, '/');
|
||||
if (slash == name) {
|
||||
directory = NULL;
|
||||
d = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (slash != NULL)
|
||||
*slash = '\0';
|
||||
|
||||
directory = directory_get_child(directory, name);
|
||||
if (directory == NULL || slash == NULL)
|
||||
d = d->FindChild(name);
|
||||
if (d == NULL || slash == NULL)
|
||||
break;
|
||||
|
||||
name = slash + 1;
|
||||
@ -194,42 +191,38 @@ directory_lookup_directory(struct directory *directory, const char *uri)
|
||||
|
||||
g_free(duplicated);
|
||||
|
||||
return directory;
|
||||
return d;
|
||||
}
|
||||
|
||||
void
|
||||
directory_add_song(struct directory *directory, struct song *song)
|
||||
directory::AddSong(struct song *song)
|
||||
{
|
||||
assert(holding_db_lock());
|
||||
assert(directory != 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
|
||||
directory_remove_song(G_GNUC_UNUSED struct directory *directory,
|
||||
struct song *song)
|
||||
directory::RemoveSong(struct song *song)
|
||||
{
|
||||
assert(holding_db_lock());
|
||||
assert(directory != NULL);
|
||||
assert(song != NULL);
|
||||
assert(song->parent == directory);
|
||||
assert(song->parent == this);
|
||||
|
||||
list_del(&song->siblings);
|
||||
}
|
||||
|
||||
struct song *
|
||||
directory_get_song(const struct directory *directory, const char *name_utf8)
|
||||
const song *
|
||||
directory::FindSong(const char *name_utf8) const
|
||||
{
|
||||
assert(holding_db_lock());
|
||||
assert(directory != NULL);
|
||||
assert(name_utf8 != NULL);
|
||||
|
||||
struct song *song;
|
||||
directory_for_each_song(song, directory) {
|
||||
assert(song->parent == directory);
|
||||
directory_for_each_song(song, this) {
|
||||
assert(song->parent == this);
|
||||
|
||||
if (strcmp(song->uri, name_utf8) == 0)
|
||||
return song;
|
||||
@ -239,29 +232,29 @@ directory_get_song(const struct directory *directory, const char *name_utf8)
|
||||
}
|
||||
|
||||
struct song *
|
||||
directory_lookup_song(struct directory *directory, const char *uri)
|
||||
directory::LookupSong(const char *uri)
|
||||
{
|
||||
char *duplicated, *base;
|
||||
|
||||
assert(holding_db_lock());
|
||||
assert(directory != NULL);
|
||||
assert(uri != NULL);
|
||||
|
||||
duplicated = g_strdup(uri);
|
||||
base = strrchr(duplicated, '/');
|
||||
|
||||
struct directory *d = this;
|
||||
if (base != NULL) {
|
||||
*base++ = 0;
|
||||
directory = directory_lookup_directory(directory, duplicated);
|
||||
if (directory == NULL) {
|
||||
d = d->LookupDirectory(duplicated);
|
||||
if (d == nullptr) {
|
||||
g_free(duplicated);
|
||||
return NULL;
|
||||
}
|
||||
} else
|
||||
base = duplicated;
|
||||
|
||||
struct song *song = directory_get_song(directory, base);
|
||||
assert(song == NULL || song->parent == directory);
|
||||
struct song *song = d->FindSong(base);
|
||||
assert(song == NULL || song->parent == d);
|
||||
|
||||
g_free(duplicated);
|
||||
return song;
|
||||
@ -278,16 +271,16 @@ directory_cmp(G_GNUC_UNUSED void *priv,
|
||||
}
|
||||
|
||||
void
|
||||
directory_sort(struct directory *directory)
|
||||
directory::Sort()
|
||||
{
|
||||
assert(holding_db_lock());
|
||||
|
||||
list_sort(NULL, &directory->children, directory_cmp);
|
||||
song_list_sort(&directory->songs);
|
||||
list_sort(NULL, &children, directory_cmp);
|
||||
song_list_sort(&songs);
|
||||
|
||||
struct directory *child;
|
||||
directory_for_each_child(child, directory)
|
||||
directory_sort(child);
|
||||
directory_for_each_child(child, this)
|
||||
child->Sort();
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -90,6 +90,154 @@ struct directory {
|
||||
bool have_stat; /* not needed if ino_t == dev_t == 0 is impossible */
|
||||
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.
|
||||
*/
|
||||
@ -105,161 +253,4 @@ isRootDirectory(const char *name)
|
||||
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
|
||||
|
@ -48,12 +48,11 @@ directory_quark(void)
|
||||
void
|
||||
directory_save(FILE *fp, const struct directory *directory)
|
||||
{
|
||||
if (!directory_is_root(directory)) {
|
||||
if (!directory->IsRoot()) {
|
||||
fprintf(fp, DIRECTORY_MTIME "%lu\n",
|
||||
(unsigned long)directory->mtime);
|
||||
|
||||
fprintf(fp, "%s%s\n", DIRECTORY_BEGIN,
|
||||
directory_get_path(directory));
|
||||
fprintf(fp, "%s%s\n", DIRECTORY_BEGIN, directory->GetPath());
|
||||
}
|
||||
|
||||
struct directory *cur;
|
||||
@ -75,9 +74,8 @@ directory_save(FILE *fp, const struct directory *directory)
|
||||
|
||||
playlist_vector_save(fp, &directory->playlists);
|
||||
|
||||
if (!directory_is_root(directory))
|
||||
fprintf(fp, DIRECTORY_END "%s\n",
|
||||
directory_get_path(directory));
|
||||
if (!directory->IsRoot())
|
||||
fprintf(fp, DIRECTORY_END "%s\n", directory->GetPath());
|
||||
}
|
||||
|
||||
static struct directory *
|
||||
@ -87,19 +85,19 @@ directory_load_subdir(FILE *fp, struct directory *parent, const char *name,
|
||||
const char *line;
|
||||
bool success;
|
||||
|
||||
if (directory_get_child(parent, name) != NULL) {
|
||||
if (parent->FindChild(name) != nullptr) {
|
||||
g_set_error(error_r, directory_quark(), 0,
|
||||
"Duplicate subdirectory '%s'", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct directory *directory = directory_new_child(parent, name);
|
||||
struct directory *directory = parent->CreateChild(name);
|
||||
|
||||
line = read_text_line(fp, buffer);
|
||||
if (line == NULL) {
|
||||
g_set_error(error_r, directory_quark(), 0,
|
||||
"Unexpected end of file");
|
||||
directory_delete(directory);
|
||||
directory->Delete();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -112,7 +110,7 @@ directory_load_subdir(FILE *fp, struct directory *parent, const char *name,
|
||||
if (line == NULL) {
|
||||
g_set_error(error_r, directory_quark(), 0,
|
||||
"Unexpected end of file");
|
||||
directory_delete(directory);
|
||||
directory->Delete();
|
||||
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)) {
|
||||
g_set_error(error_r, directory_quark(), 0,
|
||||
"Malformed line: %s", line);
|
||||
directory_delete(directory);
|
||||
directory->Delete();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
success = directory_load(fp, directory, buffer, error_r);
|
||||
if (!success) {
|
||||
directory_delete(directory);
|
||||
directory->Delete();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -152,7 +150,7 @@ directory_load(FILE *fp, struct directory *directory,
|
||||
const char *name = line + sizeof(SONG_BEGIN) - 1;
|
||||
struct song *song;
|
||||
|
||||
if (directory_get_song(directory, name) != NULL) {
|
||||
if (directory->FindSong(name) != nullptr) {
|
||||
g_set_error(error, directory_quark(), 0,
|
||||
"Duplicate song '%s'", name);
|
||||
return false;
|
||||
@ -163,7 +161,7 @@ directory_load(FILE *fp, struct directory *directory,
|
||||
if (song == NULL)
|
||||
return false;
|
||||
|
||||
directory_add_song(directory, song);
|
||||
directory->AddSong(song);
|
||||
} else if (g_str_has_prefix(line, PLAYLIST_META_BEGIN)) {
|
||||
/* duplicate the name, because
|
||||
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_fs != NULL);
|
||||
|
||||
if (directory_is_root(directory))
|
||||
if (directory->IsRoot())
|
||||
return g_strdup(music_dir_fs);
|
||||
|
||||
return map_uri_fs(directory_get_path(directory));
|
||||
return map_uri_fs(directory->GetPath());
|
||||
}
|
||||
|
||||
char *
|
||||
|
@ -161,10 +161,10 @@ song_get_uri(const struct song *song)
|
||||
assert(song != nullptr);
|
||||
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);
|
||||
else
|
||||
return g_strconcat(directory_get_path(song->parent),
|
||||
return g_strconcat(song->parent->GetPath(),
|
||||
"/", song->uri, nullptr);
|
||||
}
|
||||
|
||||
|
@ -33,9 +33,9 @@ extern "C" {
|
||||
void
|
||||
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,
|
||||
directory_get_path(song->parent), song->uri);
|
||||
song->parent->GetPath(), song->uri);
|
||||
} else {
|
||||
char *allocated;
|
||||
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 *)user_data;
|
||||
struct song *song;
|
||||
|
||||
if (memcmp(uri, data->base_uri, data->base_uri_length) != 0)
|
||||
/* should not happen, ignore silently */
|
||||
return;
|
||||
|
||||
song = directory_lookup_song(data->directory,
|
||||
uri + data->base_uri_length);
|
||||
song *song = data->directory->LookupSong(uri + data->base_uri_length);
|
||||
if (song != NULL)
|
||||
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;
|
||||
|
||||
char *allocated;
|
||||
data.base_uri = directory_get_path(directory);
|
||||
data.base_uri = directory->GetPath();
|
||||
if (*data.base_uri != 0)
|
||||
/* append slash to base_uri */
|
||||
data.base_uri = allocated =
|
||||
|
@ -43,7 +43,7 @@ update_archive_tree(struct directory *directory, char *name)
|
||||
//add dir is not there already
|
||||
db_lock();
|
||||
struct directory *subdir =
|
||||
directory_make_child(directory, name);
|
||||
directory->MakeChild(name);
|
||||
subdir->device = DEVICE_INARCHIVE;
|
||||
db_unlock();
|
||||
//create directories first
|
||||
@ -56,18 +56,18 @@ update_archive_tree(struct directory *directory, char *name)
|
||||
|
||||
//add file
|
||||
db_lock();
|
||||
struct song *song = directory_get_song(directory, name);
|
||||
struct song *song = directory->FindSong(name);
|
||||
db_unlock();
|
||||
if (song == NULL) {
|
||||
song = song_file_load(name, directory);
|
||||
if (song != NULL) {
|
||||
db_lock();
|
||||
directory_add_song(directory, song);
|
||||
directory->AddSong(song);
|
||||
db_unlock();
|
||||
|
||||
modified = true;
|
||||
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)
|
||||
{
|
||||
db_lock();
|
||||
struct directory *directory = directory_get_child(parent, name);
|
||||
directory *directory = parent->FindChild(name);
|
||||
db_unlock();
|
||||
|
||||
if (directory != NULL && directory->mtime == st->st_mtime &&
|
||||
@ -114,7 +114,7 @@ update_archive_file2(struct directory *parent, const char *name,
|
||||
if (directory == NULL) {
|
||||
g_debug("creating archive directory: %s", name);
|
||||
db_lock();
|
||||
directory = directory_new_child(parent, name);
|
||||
directory = parent->CreateChild(name);
|
||||
/* mark this directory as archive (we use device for
|
||||
this) */
|
||||
directory->device = DEVICE_INARCHIVE;
|
||||
|
@ -46,7 +46,7 @@ static struct directory *
|
||||
make_directory_if_modified(struct directory *parent, const char *name,
|
||||
const struct stat *st)
|
||||
{
|
||||
struct directory *directory = directory_get_child(parent, name);
|
||||
directory *directory = parent->FindChild(name);
|
||||
|
||||
// directory exists already
|
||||
if (directory != NULL) {
|
||||
@ -60,7 +60,7 @@ make_directory_if_modified(struct directory *parent, const char *name,
|
||||
modified = true;
|
||||
}
|
||||
|
||||
directory = directory_make_child(parent, name);
|
||||
directory = parent->MakeChild(name);
|
||||
directory->mtime = st->st_mtime;
|
||||
return directory;
|
||||
}
|
||||
@ -104,13 +104,12 @@ update_container_file(struct directory *directory,
|
||||
g_free(child_path_fs);
|
||||
|
||||
db_lock();
|
||||
directory_add_song(contdir, song);
|
||||
contdir->AddSong(song);
|
||||
db_unlock();
|
||||
|
||||
modified = true;
|
||||
|
||||
g_message("added %s/%s",
|
||||
directory_get_path(directory), vtrack);
|
||||
g_message("added %s/%s", directory->GetPath(), vtrack);
|
||||
g_free(vtrack);
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ delete_song(struct directory *dir, struct song *del)
|
||||
assert(del->parent == dir);
|
||||
|
||||
/* 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 */
|
||||
|
||||
@ -74,7 +74,7 @@ delete_directory(struct directory *directory)
|
||||
|
||||
clear_directory(directory);
|
||||
|
||||
directory_delete(directory);
|
||||
directory->Delete();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -83,14 +83,14 @@ delete_name_in(struct directory *parent, const char *name)
|
||||
bool modified = false;
|
||||
|
||||
db_lock();
|
||||
struct directory *directory = directory_get_child(parent, name);
|
||||
directory *directory = parent->FindChild(name);
|
||||
|
||||
if (directory != NULL) {
|
||||
delete_directory(directory);
|
||||
modified = true;
|
||||
}
|
||||
|
||||
struct song *song = directory_get_song(parent, name);
|
||||
struct song *song = parent->FindSong(name);
|
||||
if (song != NULL) {
|
||||
delete_song(parent, song);
|
||||
modified = true;
|
||||
|
@ -42,12 +42,12 @@ update_song_file2(struct directory *directory,
|
||||
const struct decoder_plugin *plugin)
|
||||
{
|
||||
db_lock();
|
||||
struct song *song = directory_get_song(directory, name);
|
||||
struct song *song = directory->FindSong(name);
|
||||
db_unlock();
|
||||
|
||||
if (!directory_child_access(directory, name, R_OK)) {
|
||||
g_warning("no read permissions on %s/%s",
|
||||
directory_get_path(directory), name);
|
||||
directory->GetPath(), name);
|
||||
if (song != NULL) {
|
||||
db_lock();
|
||||
delete_song(directory, song);
|
||||
@ -70,28 +70,27 @@ update_song_file2(struct directory *directory,
|
||||
}
|
||||
|
||||
if (song == NULL) {
|
||||
g_debug("reading %s/%s",
|
||||
directory_get_path(directory), name);
|
||||
g_debug("reading %s/%s", directory->GetPath(), name);
|
||||
song = song_file_load(name, directory);
|
||||
if (song == NULL) {
|
||||
g_debug("ignoring unrecognized file %s/%s",
|
||||
directory_get_path(directory), name);
|
||||
directory->GetPath(), name);
|
||||
return;
|
||||
}
|
||||
|
||||
db_lock();
|
||||
directory_add_song(directory, song);
|
||||
directory->AddSong(song);
|
||||
db_unlock();
|
||||
|
||||
modified = true;
|
||||
g_message("added %s/%s",
|
||||
directory_get_path(directory), name);
|
||||
directory->GetPath(), name);
|
||||
} else if (st->st_mtime != song->mtime || walk_discard) {
|
||||
g_message("updating %s/%s",
|
||||
directory_get_path(directory), name);
|
||||
directory->GetPath(), name);
|
||||
if (!song_file_update(song)) {
|
||||
g_debug("deleting unrecognized file %s/%s",
|
||||
directory_get_path(directory), name);
|
||||
directory->GetPath(), name);
|
||||
db_lock();
|
||||
delete_song(directory, song);
|
||||
db_unlock();
|
||||
|
@ -102,7 +102,7 @@ remove_excluded_from_directory(struct directory *directory,
|
||||
|
||||
struct directory *child, *n;
|
||||
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)) {
|
||||
delete_directory(child);
|
||||
@ -254,8 +254,7 @@ update_directory_child(struct directory *directory,
|
||||
return;
|
||||
|
||||
db_lock();
|
||||
struct directory *subdir =
|
||||
directory_make_child(directory, name);
|
||||
struct directory *subdir = directory->MakeChild(name);
|
||||
db_unlock();
|
||||
|
||||
assert(directory == subdir->parent);
|
||||
@ -423,7 +422,7 @@ static struct directory *
|
||||
directory_make_child_checked(struct directory *parent, const char *name_utf8)
|
||||
{
|
||||
db_lock();
|
||||
struct directory *directory = directory_get_child(parent, name_utf8);
|
||||
directory *directory = parent->FindChild(name_utf8);
|
||||
db_unlock();
|
||||
|
||||
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
|
||||
with potentially the same name */
|
||||
db_lock();
|
||||
struct song *conflicting = directory_get_song(parent, name_utf8);
|
||||
struct song *conflicting = parent->FindSong(name_utf8);
|
||||
if (conflicting)
|
||||
delete_song(parent, conflicting);
|
||||
|
||||
directory = directory_new_child(parent, name_utf8);
|
||||
directory = parent->CreateChild(name_utf8);
|
||||
db_unlock();
|
||||
|
||||
directory_set_stat(directory, &st);
|
||||
|
@ -168,7 +168,7 @@ ProxyDatabase::Open(GError **error_r)
|
||||
return false;
|
||||
}
|
||||
|
||||
root = directory_new_root();
|
||||
root = directory::NewRoot();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -178,7 +178,7 @@ ProxyDatabase::Close()
|
||||
{
|
||||
assert(connection != nullptr);
|
||||
|
||||
directory_free(root);
|
||||
root->Free();
|
||||
mpd_connection_free(connection);
|
||||
}
|
||||
|
||||
@ -241,9 +241,9 @@ Visit(struct mpd_connection *connection,
|
||||
|
||||
if (visit_directory) {
|
||||
struct directory *d =
|
||||
directory_new(path, &detached_root);
|
||||
directory::NewGeneric(path, &detached_root);
|
||||
bool success = visit_directory(*d, error_r);
|
||||
directory_free(d);
|
||||
d->Free();
|
||||
if (!success)
|
||||
return false;
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ SimpleDatabase::Load(GError **error_r)
|
||||
bool
|
||||
SimpleDatabase::Open(GError **error_r)
|
||||
{
|
||||
root = directory_new_root();
|
||||
root = directory::NewRoot();
|
||||
mtime = 0;
|
||||
|
||||
#ifndef NDEBUG
|
||||
@ -189,7 +189,7 @@ SimpleDatabase::Open(GError **error_r)
|
||||
|
||||
GError *error = NULL;
|
||||
if (!Load(&error)) {
|
||||
directory_free(root);
|
||||
root->Free();
|
||||
|
||||
g_warning("Failed to load database: %s", error->message);
|
||||
g_error_free(error);
|
||||
@ -197,7 +197,7 @@ SimpleDatabase::Open(GError **error_r)
|
||||
if (!Check(error_r))
|
||||
return false;
|
||||
|
||||
root = directory_new_root();
|
||||
root = directory::NewRoot();
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -209,7 +209,7 @@ SimpleDatabase::Close()
|
||||
assert(root != NULL);
|
||||
assert(borrowed_song_count == 0);
|
||||
|
||||
directory_free(root);
|
||||
root->Free();
|
||||
}
|
||||
|
||||
struct song *
|
||||
@ -218,7 +218,7 @@ SimpleDatabase::GetSong(const char *uri, GError **error_r) const
|
||||
assert(root != NULL);
|
||||
|
||||
db_lock();
|
||||
struct song *song = directory_lookup_song(root, uri);
|
||||
song *song = root->LookupSong(uri);
|
||||
db_unlock();
|
||||
if (song == NULL)
|
||||
g_set_error(error_r, db_quark(), DB_NOT_FOUND,
|
||||
@ -250,7 +250,7 @@ SimpleDatabase::LookupDirectory(const char *uri) const
|
||||
assert(uri != NULL);
|
||||
|
||||
ScopeDatabaseLock protect;
|
||||
return directory_lookup_directory(root, uri);
|
||||
return root->LookupDirectory(uri);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -262,12 +262,10 @@ SimpleDatabase::Visit(const DatabaseSelection &selection,
|
||||
{
|
||||
ScopeDatabaseLock protect;
|
||||
|
||||
const struct directory *directory =
|
||||
directory_lookup_directory(root, selection.uri);
|
||||
const directory *directory = root->LookupDirectory(selection.uri);
|
||||
if (directory == NULL) {
|
||||
if (visit_song) {
|
||||
struct song *song =
|
||||
directory_lookup_song(root, selection.uri);
|
||||
song *song = root->LookupSong(selection.uri);
|
||||
if (song != nullptr)
|
||||
return !selection.Match(*song) ||
|
||||
visit_song(*song, error_r);
|
||||
@ -310,10 +308,10 @@ SimpleDatabase::Save(GError **error_r)
|
||||
db_lock();
|
||||
|
||||
g_debug("removing empty directories from DB");
|
||||
directory_prune_empty(root);
|
||||
root->PruneEmpty();
|
||||
|
||||
g_debug("sorting DB");
|
||||
directory_sort(root);
|
||||
root->Sort();
|
||||
|
||||
db_unlock();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user