directory: don't pass fd to traverseAllIn() callbacks

Database traversal should be generic, and not bound to a client
connection.  This is the first step: no file descriptor for the
callback functions forEachSong() and forEachDir().  If a callback
needs the file descriptor, it has to be passed in the void*data
pointer somehow; some callbacks might need a new struct for passing
more than one parameter.  This might look a bit cumbersome right now,
but our goal is to have a clean API.
This commit is contained in:
Max Kellermann 2008-09-07 13:48:24 +02:00
parent d8ef33b710
commit 528be8a0a9
4 changed files with 81 additions and 51 deletions

View File

@ -46,7 +46,7 @@ typedef struct _SearchStats {
unsigned long playTime; unsigned long playTime;
} SearchStats; } SearchStats;
static int countSongsInDirectory(mpd_unused int fd, Directory * directory, static int countSongsInDirectory(Directory * directory,
void *data) void *data)
{ {
int *count = (int *)data; int *count = (int *)data;
@ -56,24 +56,32 @@ static int countSongsInDirectory(mpd_unused int fd, Directory * directory,
return 0; return 0;
} }
static int printDirectoryInDirectory(int fd, Directory * directory, static int printDirectoryInDirectory(Directory * directory, void *data)
mpd_unused void *data)
{ {
int fd = (int)(size_t)data;
if (directory->path) { if (directory->path) {
fdprintf(fd, "directory: %s\n", getDirectoryPath(directory)); fdprintf(fd, "directory: %s\n", getDirectoryPath(directory));
} }
return 0; return 0;
} }
static int printSongInDirectory(int fd, Song * song, mpd_unused void *data) static int printSongInDirectory(Song * song, mpd_unused void *data)
{ {
int fd = (int)(size_t)data;
printSongUrl(fd, song); printSongUrl(fd, song);
return 0; return 0;
} }
static int searchInDirectory(int fd, Song * song, void *data) struct search_data {
int fd;
LocateTagItemArray array;
};
static int searchInDirectory(Song * song, void *_data)
{ {
LocateTagItemArray *array = data; struct search_data *data = _data;
int fd = data->fd;
LocateTagItemArray *array = &data->array;
if (strstrSearchTags(song, array->numItems, array->items)) if (strstrSearchTags(song, array->numItems, array->items))
printSongInfo(fd, song); printSongInfo(fd, song);
@ -88,17 +96,18 @@ int searchForSongsIn(int fd, const char *name, int numItems,
int i; int i;
char **originalNeedles = xmalloc(numItems * sizeof(char *)); char **originalNeedles = xmalloc(numItems * sizeof(char *));
LocateTagItemArray array; struct search_data data;
for (i = 0; i < numItems; i++) { for (i = 0; i < numItems; i++) {
originalNeedles[i] = items[i].needle; originalNeedles[i] = items[i].needle;
items[i].needle = strDupToUpper(originalNeedles[i]); items[i].needle = strDupToUpper(originalNeedles[i]);
} }
array.numItems = numItems; data.fd = fd;
array.items = items; data.array.numItems = numItems;
data.array.items = items;
ret = traverseAllIn(fd, name, searchInDirectory, NULL, &array); ret = traverseAllIn(fd, name, searchInDirectory, NULL, &data);
for (i = 0; i < numItems; i++) { for (i = 0; i < numItems; i++) {
free(items[i].needle); free(items[i].needle);
@ -110,9 +119,11 @@ int searchForSongsIn(int fd, const char *name, int numItems,
return ret; return ret;
} }
static int findInDirectory(int fd, Song * song, void *data) static int findInDirectory(Song * song, void *_data)
{ {
LocateTagItemArray *array = data; struct search_data *data = _data;
int fd = data->fd;
LocateTagItemArray *array = &data->array;
if (tagItemsFoundAndMatches(song, array->numItems, array->items)) if (tagItemsFoundAndMatches(song, array->numItems, array->items))
printSongInfo(fd, song); printSongInfo(fd, song);
@ -122,12 +133,13 @@ static int findInDirectory(int fd, Song * song, void *data)
int findSongsIn(int fd, const char *name, int numItems, LocateTagItem * items) int findSongsIn(int fd, const char *name, int numItems, LocateTagItem * items)
{ {
LocateTagItemArray array; struct search_data data;
array.numItems = numItems; data.fd = fd;
array.items = items; data.array.numItems = numItems;
data.array.items = items;
return traverseAllIn(fd, name, findInDirectory, NULL, (void *)&array); return traverseAllIn(fd, name, findInDirectory, NULL, &data);
} }
static void printSearchStats(int fd, SearchStats *stats) static void printSearchStats(int fd, SearchStats *stats)
@ -136,7 +148,7 @@ static void printSearchStats(int fd, SearchStats *stats)
fdprintf(fd, "playtime: %li\n", stats->playTime); fdprintf(fd, "playtime: %li\n", stats->playTime);
} }
static int searchStatsInDirectory(mpd_unused int fd, Song * song, void *data) static int searchStatsInDirectory(Song * song, void *data)
{ {
SearchStats *stats = data; SearchStats *stats = data;
@ -171,19 +183,25 @@ int searchStatsForSongsIn(int fd, const char *name, int numItems,
int printAllIn(int fd, const char *name) int printAllIn(int fd, const char *name)
{ {
return traverseAllIn(fd, name, printSongInDirectory, return traverseAllIn(fd, name, printSongInDirectory,
printDirectoryInDirectory, NULL); printDirectoryInDirectory, (void*)(size_t)fd);
} }
static int directoryAddSongToPlaylist(mpd_unused int fd, Song * song, static int directoryAddSongToPlaylist(Song * song, mpd_unused void *data)
mpd_unused void *data)
{ {
return addSongToPlaylist(song, NULL); return addSongToPlaylist(song, NULL);
} }
static int directoryAddSongToStoredPlaylist(mpd_unused int fd, Song *song, struct add_data {
void *data) const char *path;
};
static int directoryAddSongToStoredPlaylist(Song *song, void *_data)
{ {
return appendSongToStoredPlaylistByPath((char *)data, song); struct add_data *data = _data;
if (appendSongToStoredPlaylistByPath(data->path, song) != 0)
return -1;
return 0;
} }
int addAllIn(int fd, const char *name) int addAllIn(int fd, const char *name)
@ -193,16 +211,22 @@ int addAllIn(int fd, const char *name)
int addAllInToStoredPlaylist(int fd, const char *name, const char *utf8file) int addAllInToStoredPlaylist(int fd, const char *name, const char *utf8file)
{ {
struct add_data data = {
.path = utf8file,
};
return traverseAllIn(fd, name, directoryAddSongToStoredPlaylist, NULL, return traverseAllIn(fd, name, directoryAddSongToStoredPlaylist, NULL,
(void *)utf8file); &data);
} }
static int directoryPrintSongInfo(int fd, Song * song, mpd_unused void *data) static int directoryPrintSongInfo(Song * song, void *data)
{ {
int fd = (int)(size_t)data;
return printSongInfo(fd, song); return printSongInfo(fd, song);
} }
static int sumSongTime(mpd_unused int fd, Song * song, void *data) static int sumSongTime(Song * song, void *data)
{ {
unsigned long *sum_time = (unsigned long *)data; unsigned long *sum_time = (unsigned long *)data;
@ -215,7 +239,7 @@ static int sumSongTime(mpd_unused int fd, Song * song, void *data)
int printInfoForAllIn(int fd, const char *name) int printInfoForAllIn(int fd, const char *name)
{ {
return traverseAllIn(fd, name, directoryPrintSongInfo, return traverseAllIn(fd, name, directoryPrintSongInfo,
printDirectoryInDirectory, NULL); printDirectoryInDirectory, (void*)(size_t)fd);
} }
int countSongsIn(int fd, const char *name) int countSongsIn(int fd, const char *name)
@ -275,13 +299,19 @@ static void visitTag(int fd, Song * song, enum tag_type tagType)
} }
} }
static int listUniqueTagsInDirectory(int fd, Song * song, void *data) struct list_tags_data {
int fd;
ListCommandItem *item;
};
static int listUniqueTagsInDirectory(Song * song, void *_data)
{ {
ListCommandItem *item = data; struct list_tags_data *data = _data;
ListCommandItem *item = data->item;
if (tagItemsFoundAndMatches(song, item->numConditionals, if (tagItemsFoundAndMatches(song, item->numConditionals,
item->conditionals)) { item->conditionals)) {
visitTag(fd, song, item->tagType); visitTag(data->fd, song, item->tagType);
} }
return 0; return 0;
@ -293,13 +323,17 @@ int listAllUniqueTags(int fd, int type, int numConditionals,
int ret; int ret;
ListCommandItem *item = newListCommandItem(type, numConditionals, ListCommandItem *item = newListCommandItem(type, numConditionals,
conditionals); conditionals);
struct list_tags_data data = {
.fd = fd,
.item = item,
};
if (type >= 0 && type <= TAG_NUM_OF_ITEM_TYPES) { if (type >= 0 && type <= TAG_NUM_OF_ITEM_TYPES) {
resetVisitedFlagsInTagTracker(type); resetVisitedFlagsInTagTracker(type);
} }
ret = traverseAllIn(fd, NULL, listUniqueTagsInDirectory, NULL, ret = traverseAllIn(fd, NULL, listUniqueTagsInDirectory, NULL,
(void *)item); &data);
if (type >= 0 && type <= TAG_NUM_OF_ITEM_TYPES) { if (type >= 0 && type <= TAG_NUM_OF_ITEM_TYPES) {
printVisitedInTagTracker(fd, type); printVisitedInTagTracker(fd, type);
@ -310,9 +344,7 @@ int listAllUniqueTags(int fd, int type, int numConditionals,
return ret; return ret;
} }
static int sumSavedFilenameMemoryInDirectory(mpd_unused int fd, static int sumSavedFilenameMemoryInDirectory(Directory * dir, void *data)
Directory * dir,
void *data)
{ {
int *sum = data; int *sum = data;
@ -325,8 +357,7 @@ static int sumSavedFilenameMemoryInDirectory(mpd_unused int fd,
return 0; return 0;
} }
static int sumSavedFilenameMemoryInSong(mpd_unused int fd, Song * song, static int sumSavedFilenameMemoryInSong(Song * song, void *data)
void *data)
{ {
int *sum = data; int *sum = data;

View File

@ -1182,11 +1182,10 @@ void updateMp3Directory(void)
return; return;
} }
static int traverseAllInSubDirectory(int fd, Directory * directory, static int traverseAllInSubDirectory(Directory * directory,
int (*forEachSong) (int, Song *, int (*forEachSong) (Song *, void *),
void *), int (*forEachDir) (Directory *, void *),
int (*forEachDir) (int, Directory *, void *data)
void *), void *data)
{ {
ListNode *node = directory->songs->firstNode; ListNode *node = directory->songs->firstNode;
Song *song; Song *song;
@ -1194,7 +1193,7 @@ static int traverseAllInSubDirectory(int fd, Directory * directory,
int errFlag = 0; int errFlag = 0;
if (forEachDir) { if (forEachDir) {
errFlag = forEachDir(fd, directory, data); errFlag = forEachDir(directory, data);
if (errFlag) if (errFlag)
return errFlag; return errFlag;
} }
@ -1202,7 +1201,7 @@ static int traverseAllInSubDirectory(int fd, Directory * directory,
if (forEachSong) { if (forEachSong) {
while (node != NULL && !errFlag) { while (node != NULL && !errFlag) {
song = (Song *) node->data; song = (Song *) node->data;
errFlag = forEachSong(fd, song, data); errFlag = forEachSong(song, data);
node = node->nextNode; node = node->nextNode;
} }
if (errFlag) if (errFlag)
@ -1213,7 +1212,7 @@ static int traverseAllInSubDirectory(int fd, Directory * directory,
while (node != NULL && !errFlag) { while (node != NULL && !errFlag) {
dir = (Directory *) node->data; dir = (Directory *) node->data;
errFlag = traverseAllInSubDirectory(fd, dir, forEachSong, errFlag = traverseAllInSubDirectory(dir, forEachSong,
forEachDir, data); forEachDir, data);
node = node->nextNode; node = node->nextNode;
} }
@ -1222,22 +1221,22 @@ static int traverseAllInSubDirectory(int fd, Directory * directory,
} }
int traverseAllIn(int fd, const char *name, int traverseAllIn(int fd, const char *name,
int (*forEachSong) (int, Song *, void *), int (*forEachSong) (Song *, void *),
int (*forEachDir) (int, Directory *, void *), void *data) int (*forEachDir) (Directory *, void *), void *data)
{ {
Directory *directory; Directory *directory;
if ((directory = getDirectory(name)) == NULL) { if ((directory = getDirectory(name)) == NULL) {
Song *song; Song *song;
if ((song = getSongFromDB(name)) && forEachSong) { if ((song = getSongFromDB(name)) && forEachSong) {
return forEachSong(fd, song, data); return forEachSong(song, data);
} }
commandError(fd, ACK_ERROR_NO_EXIST, commandError(fd, ACK_ERROR_NO_EXIST,
"directory or file not found"); "directory or file not found");
return -1; return -1;
} }
return traverseAllInSubDirectory(fd, directory, forEachSong, forEachDir, return traverseAllInSubDirectory(directory, forEachSong, forEachDir,
data); data);
} }

View File

@ -65,8 +65,8 @@ Song *getSongFromDB(const char *file);
time_t getDbModTime(void); time_t getDbModTime(void);
int traverseAllIn(int fd, const char *name, int traverseAllIn(int fd, const char *name,
int (*forEachSong) (int, Song *, void *), int (*forEachSong) (Song *, void *),
int (*forEachDir) (int, Directory *, void *), void *data); int (*forEachDir) (Directory *, void *), void *data);
#define getDirectoryPath(dir) ((dir && dir->path) ? dir->path : "") #define getDirectoryPath(dir) ((dir && dir->path) ? dir->path : "")

View File

@ -37,7 +37,7 @@ struct visited {
static struct visited *visited_heads[TAG_NUM_OF_ITEM_TYPES]; static struct visited *visited_heads[TAG_NUM_OF_ITEM_TYPES];
static unsigned num_visited[TAG_NUM_OF_ITEM_TYPES]; static unsigned num_visited[TAG_NUM_OF_ITEM_TYPES];
static int visit_tag_items(int fd mpd_unused, Song *song, void *data) static int visit_tag_items(Song *song, void *data)
{ {
enum tag_type type = (enum tag_type)(size_t)data; enum tag_type type = (enum tag_type)(size_t)data;
unsigned i; unsigned i;