Handle streams separately in tree_add_track()
[cmus.git] / track_info.c
blob179859fdb4e7fe5adb5cd95c856c2c093bc66382
1 /*
2 * Copyright 2004-2005 Timo Hirvonen
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17 * 02111-1307, USA.
20 #include "track_info.h"
21 #include "comment.h"
22 #include "uchar.h"
23 #include "misc.h"
24 #include "xmalloc.h"
25 #include "utils.h"
26 #include "debug.h"
28 #include <string.h>
30 static void track_info_free(struct track_info *ti)
32 keyvals_free(ti->comments);
33 free(ti);
36 struct track_info *track_info_new(const char *filename)
38 struct track_info *ti;
39 int size = strlen(filename) + 1;
41 ti = xmalloc(sizeof(struct track_info) + size);
42 memcpy(ti->filename, filename, size);
43 ti->ref = 1;
44 return ti;
47 struct track_info *track_info_url_new(const char *url)
49 struct track_info *ti = track_info_new(url);
50 ti->comments = xnew0(struct keyval, 1);
51 ti->duration = -1;
52 ti->mtime = -1;
53 return ti;
56 void track_info_ref(struct track_info *ti)
58 BUG_ON(ti->ref < 1);
59 ti->ref++;
62 void track_info_unref(struct track_info *ti)
64 BUG_ON(ti->ref < 1);
65 ti->ref--;
66 if (ti->ref == 0)
67 track_info_free(ti);
70 int track_info_has_tag(const struct track_info *ti)
72 return keyvals_get_val(ti->comments, "artist") ||
73 keyvals_get_val(ti->comments, "album") ||
74 keyvals_get_val(ti->comments, "title");
77 int track_info_matches(struct track_info *ti, const char *text, unsigned int flags)
79 const char *artist = keyvals_get_val(ti->comments, "artist");
80 const char *album = keyvals_get_val(ti->comments, "album");
81 const char *title = keyvals_get_val(ti->comments, "title");
82 char **words;
83 int i, matched = 1;
85 words = get_words(text);
86 if (words[0] == NULL)
87 matched = 0;
88 for (i = 0; words[i]; i++) {
89 const char *word = words[i];
91 if ((flags & TI_MATCH_ARTIST && artist) ||
92 (flags & TI_MATCH_ALBUM && album) ||
93 (flags & TI_MATCH_TITLE && title)) {
94 if (flags & TI_MATCH_ARTIST && artist && u_strcasestr(artist, word))
95 continue;
96 if (flags & TI_MATCH_ALBUM && album && u_strcasestr(album, word))
97 continue;
98 if (flags & TI_MATCH_TITLE && title && u_strcasestr(title, word))
99 continue;
100 } else {
101 /* compare with url or filename without path */
102 char *filename = ti->filename;
104 if (!is_url(filename)) {
105 char *slash = strrchr(ti->filename, '/');
106 if (slash)
107 filename = slash + 1;
109 if (u_strcasestr_filename(filename, word))
110 continue;
112 matched = 0;
113 break;
115 free_str_array(words);
116 return matched;
119 static int xstrcasecmp(const char *a, const char *b)
121 if (a == NULL) {
122 if (b == NULL)
123 return 0;
124 return -1;
125 } else if (b == NULL) {
126 return 1;
128 return u_strcasecmp(a, b);
131 int track_info_cmp(const struct track_info *a, const struct track_info *b, const char * const *keys)
133 int i, res = 0;
135 for (i = 0; keys[i]; i++) {
136 const char *key = keys[i];
137 const char *av, *bv;
139 /* numeric compare for tracknumber and discnumber */
140 if (strcmp(key, "tracknumber") == 0) {
141 res = comments_get_int(a->comments, key) -
142 comments_get_int(b->comments, key);
143 if (res)
144 break;
145 continue;
147 if (strcmp(key, "discnumber") == 0) {
148 res = comments_get_int(a->comments, key) -
149 comments_get_int(b->comments, key);
150 if (res)
151 break;
152 continue;
154 if (strcmp(key, "filename") == 0) {
155 /* NOTE: filenames are not necessarily UTF-8 */
156 res = strcasecmp(a->filename, b->filename);
157 if (res)
158 break;
159 continue;
161 if (strcmp(key, "albumartist") == 0) {
162 av = comments_get_albumartist(a->comments);
163 bv = comments_get_albumartist(b->comments);
164 res = xstrcasecmp(av, bv);
165 if (res)
166 break;
167 continue;
170 av = keyvals_get_val(a->comments, key);
171 bv = keyvals_get_val(b->comments, key);
172 res = xstrcasecmp(av, bv);
173 if (res)
174 break;
176 return res;