2 * Copyright (C) 2003-2010 The Music Player Daemon Project
3 * http://www.musicpd.org
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "directory.h"
32 directory_new(const char *path
, struct directory
*parent
)
34 struct directory
*directory
;
35 size_t pathlen
= strlen(path
);
38 assert((*path
== 0) == (parent
== NULL
));
40 directory
= g_malloc0(sizeof(*directory
) -
41 sizeof(directory
->path
) + pathlen
+ 1);
42 directory
->parent
= parent
;
43 memcpy(directory
->path
, path
, pathlen
+ 1);
49 directory_free(struct directory
*directory
)
51 for (unsigned i
= 0; i
< directory
->songs
.nr
; ++i
)
52 song_free(directory
->songs
.base
[i
]);
54 for (unsigned i
= 0; i
< directory
->children
.nr
; ++i
)
55 directory_free(directory
->children
.base
[i
]);
57 dirvec_destroy(&directory
->children
);
58 songvec_destroy(&directory
->songs
);
60 /* this resets last dir returned */
61 /*directory_get_path(NULL); */
65 directory_get_name(const struct directory
*directory
)
67 return g_basename(directory
->path
);
71 directory_prune_empty(struct directory
*directory
)
74 struct dirvec
*dv
= &directory
->children
;
76 for (i
= dv
->nr
; --i
>= 0; ) {
77 struct directory
*child
= dv
->base
[i
];
79 directory_prune_empty(child
);
81 if (directory_is_empty(child
)) {
82 dirvec_delete(dv
, child
);
83 directory_free(child
);
91 directory_lookup_directory(struct directory
*directory
, const char *uri
)
93 struct directory
*cur
= directory
;
94 struct directory
*found
= NULL
;
100 if (isRootDirectory(uri
))
103 duplicated
= g_strdup(uri
);
104 locate
= strchr(duplicated
, '/');
108 if (!(found
= directory_get_child(cur
, duplicated
)))
110 assert(cur
== found
->parent
);
115 locate
= strchr(locate
+ 1, '/');
124 directory_lookup_song(struct directory
*directory
, const char *uri
)
126 char *duplicated
, *base
;
129 assert(directory
!= NULL
);
132 duplicated
= g_strdup(uri
);
133 base
= strrchr(duplicated
, '/');
137 directory
= directory_lookup_directory(directory
, duplicated
);
138 if (directory
== NULL
) {
145 song
= songvec_find(&directory
->songs
, base
);
146 assert(song
== NULL
|| song
->parent
== directory
);
154 directory_sort(struct directory
*directory
)
157 struct dirvec
*dv
= &directory
->children
;
160 songvec_sort(&directory
->songs
);
162 for (i
= dv
->nr
; --i
>= 0; )
163 directory_sort(dv
->base
[i
]);
167 directory_walk(struct directory
*directory
,
168 int (*forEachSong
)(struct song
*, void *),
169 int (*forEachDir
)(struct directory
*, void *),
172 struct dirvec
*dv
= &directory
->children
;
176 if (forEachDir
&& (err
= forEachDir(directory
, data
)) < 0)
180 err
= songvec_for_each(&directory
->songs
, forEachSong
, data
);
185 for (j
= 0; err
>= 0 && j
< dv
->nr
; ++j
)
186 err
= directory_walk(dv
->base
[j
], forEachSong
,