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.
22 #include "directory.h"
30 static GMutex
*nr_lock
= NULL
;
32 static size_t dv_size(const struct dirvec
*dv
)
34 return dv
->nr
* sizeof(struct directory
*);
37 /* Only used for sorting/searching a dirvec, not general purpose compares */
38 static int dirvec_cmp(const void *d1
, const void *d2
)
40 const struct directory
*a
= ((const struct directory
* const *)d1
)[0];
41 const struct directory
*b
= ((const struct directory
* const *)d2
)[0];
42 return g_utf8_collate(a
->path
, b
->path
);
45 void dirvec_init(void)
47 g_assert(nr_lock
== NULL
);
48 nr_lock
= g_mutex_new();
51 void dirvec_deinit(void)
53 g_assert(nr_lock
!= NULL
);
54 g_mutex_free(nr_lock
);
58 void dirvec_sort(struct dirvec
*dv
)
60 g_mutex_lock(nr_lock
);
61 qsort(dv
->base
, dv
->nr
, sizeof(struct directory
*), dirvec_cmp
);
62 g_mutex_unlock(nr_lock
);
65 struct directory
*dirvec_find(const struct dirvec
*dv
, const char *path
)
69 struct directory
*ret
= NULL
;
71 base
= g_path_get_basename(path
);
73 g_mutex_lock(nr_lock
);
74 for (i
= dv
->nr
; --i
>= 0; )
75 if (!strcmp(directory_get_name(dv
->base
[i
]), base
)) {
79 g_mutex_unlock(nr_lock
);
85 int dirvec_delete(struct dirvec
*dv
, struct directory
*del
)
89 g_mutex_lock(nr_lock
);
90 for (i
= 0; i
< dv
->nr
; ++i
) {
91 if (dv
->base
[i
] != del
)
93 /* we _don't_ call directory_free() here */
95 g_mutex_unlock(nr_lock
);
100 memmove(&dv
->base
[i
], &dv
->base
[i
+ 1],
101 (dv
->nr
- i
) * sizeof(struct directory
*));
102 dv
->base
= g_realloc(dv
->base
, dv_size(dv
));
106 g_mutex_unlock(nr_lock
);
111 void dirvec_add(struct dirvec
*dv
, struct directory
*add
)
113 g_mutex_lock(nr_lock
);
115 dv
->base
= g_realloc(dv
->base
, dv_size(dv
));
116 dv
->base
[dv
->nr
- 1] = add
;
117 g_mutex_unlock(nr_lock
);
120 void dirvec_destroy(struct dirvec
*dv
)
122 g_mutex_lock(nr_lock
);
124 g_mutex_unlock(nr_lock
);
131 int dirvec_for_each(const struct dirvec
*dv
,
132 int (*fn
)(struct directory
*, void *), void *arg
)
137 g_mutex_lock(nr_lock
);
138 for (i
= 0; i
< dv
->nr
; ) {
139 struct directory
*dir
= dv
->base
[i
];
143 g_mutex_unlock(nr_lock
);
144 if (fn(dir
, arg
) < 0)
146 g_mutex_lock(nr_lock
); /* dv->nr may change in fn() */
147 if (prev_nr
== dv
->nr
)
150 g_mutex_unlock(nr_lock
);