aboutsummaryrefslogtreecommitdiffstats
path: root/src/directory.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/directory.h')
-rw-r--r--src/directory.h174
1 files changed, 151 insertions, 23 deletions
diff --git a/src/directory.h b/src/directory.h
index 9c0a9b567..dc664a433 100644
--- a/src/directory.h
+++ b/src/directory.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2010 The Music Player Daemon Project
+ * Copyright (C) 2003-2011 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -21,10 +21,9 @@
#define MPD_DIRECTORY_H
#include "check.h"
-#include "dirvec.h"
-#include "songvec.h"
-#include "playlist_vector.h"
+#include "util/list.h"
+#include <glib.h>
#include <stdbool.h>
#include <sys/types.h>
@@ -33,11 +32,55 @@
#define DEVICE_INARCHIVE (dev_t)(-1)
#define DEVICE_CONTAINER (dev_t)(-2)
+#define directory_for_each_child(pos, directory) \
+ list_for_each_entry(pos, &directory->children, siblings)
+
+#define directory_for_each_child_safe(pos, n, directory) \
+ list_for_each_entry_safe(pos, n, &directory->children, siblings)
+
+#define directory_for_each_song(pos, directory) \
+ list_for_each_entry(pos, &directory->songs, siblings)
+
+#define directory_for_each_song_safe(pos, n, directory) \
+ list_for_each_entry_safe(pos, n, &directory->songs, siblings)
+
+#define directory_for_each_playlist(pos, directory) \
+ list_for_each_entry(pos, &directory->playlists, siblings)
+
+#define directory_for_each_playlist_safe(pos, n, directory) \
+ list_for_each_entry_safe(pos, n, &directory->playlists, siblings)
+
+struct song;
+struct db_visitor;
+
struct directory {
- struct dirvec children;
- struct songvec songs;
+ /**
+ * Pointers to the siblings of this directory within the
+ * parent directory. It is unused (undefined) in the root
+ * directory.
+ *
+ * This attribute is protected with the global #db_mutex.
+ * Read access in the update thread does not need protection.
+ */
+ struct list_head siblings;
+
+ /**
+ * A doubly linked list of child directories.
+ *
+ * This attribute is protected with the global #db_mutex.
+ * Read access in the update thread does not need protection.
+ */
+ struct list_head children;
- struct playlist_vector playlists;
+ /**
+ * A doubly linked list of songs within this directory.
+ *
+ * This attribute is protected with the global #db_mutex.
+ * Read access in the update thread does not need protection.
+ */
+ struct list_head songs;
+
+ struct list_head playlists;
struct directory *parent;
time_t mtime;
@@ -53,17 +96,45 @@ isRootDirectory(const char *name)
return name[0] == 0 || (name[0] == '/' && name[1] == 0);
}
+/**
+ * Generic constructor for #directory object.
+ */
+G_GNUC_MALLOC
struct directory *
directory_new(const char *dirname, struct directory *parent);
+/**
+ * Create a new root #directory object.
+ */
+G_GNUC_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 directory->children.nr == 0 && directory->songs.nr == 0 &&
- playlist_vector_is_empty(&directory->playlists);
+ return list_empty(&directory->children) &&
+ list_empty(&directory->songs) &&
+ list_empty(&directory->playlists);
}
static inline const char *
@@ -84,23 +155,47 @@ directory_is_root(const struct directory *directory)
/**
* Returns the base name of the directory.
*/
+G_GNUC_PURE
const char *
directory_get_name(const struct directory *directory);
-static inline struct directory *
-directory_get_child(const struct directory *directory, const char *name)
-{
- return dirvec_find(&directory->children, name);
-}
+/**
+ * Caller must lock the #db_mutex.
+ */
+G_GNUC_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
+ */
+G_GNUC_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_new_child(struct directory *directory, const char *name)
+directory_make_child(struct directory *directory, const char *name_utf8)
{
- struct directory *subdir = directory_new(name, directory);
- dirvec_add(&directory->children, subdir);
- return subdir;
+ 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);
@@ -115,8 +210,34 @@ 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.
+ */
+G_GNUC_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
@@ -124,13 +245,20 @@ directory_lookup_directory(struct directory *directory, const char *uri);
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);
-int
-directory_walk(struct directory *directory,
- int (*forEachSong)(struct song *, void *),
- int (*forEachDir)(struct directory *, void *),
- void *data);
+/**
+ * Caller must lock #db_mutex.
+ */
+bool
+directory_walk(const struct directory *directory, bool recursive,
+ const struct db_visitor *visitor, void *ctx,
+ GError **error_r);
#endif