bb1414430ddb7f5a489b327e351dbe5731293dd3
[lms] / lightmediascanner / src / lib / lightmediascanner_utils.c
1 /**
2  * Copyright (C) 2007 by INdT
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser 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 02111-1307, USA.
17  *
18  * @author Gustavo Sverzut Barbieri <gustavo.barbieri@openbossa.org>
19  */
20
21 #include <lightmediascanner_utils.h>
22 #include <ctype.h>
23 #include <stdlib.h>
24 #include <alloca.h>
25
26 /**
27  * Strips string, in place.
28  *
29  * @param str string to be stripped.
30  * @param p_len string length to analyse, also the place where the final size
31  *        is stored.
32  */
33 void
34 lms_strstrip(char *str, unsigned int *p_len)
35 {
36     int i, len;
37     char *p;
38
39     len = *p_len;
40
41     if (len == 0)
42         return;
43
44     if (*str == '\0') {
45         *p_len = 0;
46         return;
47     }
48
49     p = str + len - 1;
50     for (i = len - 1; i >= 0; i--) {
51         if (isspace(*p) || *p == '\0') {
52             *p = '\0';
53             len--;
54             p--;
55         } else
56             break;
57     }
58     if (len == 0) {
59         *p_len = 0;
60         return;
61     }
62
63     p = str;
64     for (i = 0; i < len; i++) {
65         if (isspace(*p))
66             p++;
67         else
68             break;
69     }
70     len -= i;
71     if (len == 0) {
72         *str = '\0';
73         *p_len = 0;
74         return;
75     }
76
77     *p_len = len;
78
79     if (str < p)
80         for (; len >= 0; len--, str++, p++)
81             *str = *p;
82 }
83
84 /**
85  * If string exists, strips it, in place, free if *p_len = 0
86  *
87  * @param p_str pointer to string to be stripped.
88  * @param p_len string length to analyse, also the place where the final size
89  *        is stored.
90  *
91  * @note this will call free() on *p_str if it becomes empty.
92  */
93 void
94 lms_strstrip_and_free(char **p_str, unsigned int *p_len)
95 {
96     if (!*p_str)
97         return;
98
99     lms_strstrip(*p_str, p_len);
100     if (*p_len == 0) {
101         free(*p_str);
102         *p_str = NULL;
103     }
104 }
105
106 /**
107  * lms_string_size version of lms_strstrip_and_free().
108  *
109  * @param *p pointer to lms_string_size to be stripped.
110  *
111  * @note this will call free() on lms_string_size->str if it becomes empty.
112  */
113 void
114 lms_string_size_strip_and_free(struct lms_string_size *p)
115 {
116     if (!*p->str)
117         return;
118
119     lms_strstrip(p->str, &p->len);
120     if (p->len == 0) {
121         free(p->str);
122         p->str = NULL;
123     }
124 }
125
126
127 /**
128  * Find out which of the given extensions matches the given name.
129  *
130  * @param name string to analyse.
131  * @param name_len string length.
132  * @param exts array of extensions to be checked.
133  * @param exts_len number of items in array @p exts
134  *
135  * @return index in @p exts or -1 if it doesn't match none.
136  */
137 int
138 lms_which_extension(const char *name, unsigned int name_len, const struct lms_string_size *exts, unsigned int exts_len) {
139     int i;
140     unsigned int *exts_pos;
141     const char *s;
142
143     exts_pos = alloca(exts_len * sizeof(*exts_pos));
144     for (i = 0; i < exts_len; i++)
145         exts_pos[i] = exts[i].len;
146
147     for (s = name + name_len - 1; s >= name; s--) {
148         int i, match;
149         char c1, c2;
150
151         c1 = *s;
152         if (c1 >= 'a')
153             c2 = c1;
154         else
155             c2 = 'a' + c1 - 'A';
156
157         match = 0;
158         for (i = 0; i < exts_len; i++) {
159             if (exts_pos[i] > 0) {
160                 char ce;
161
162                 ce = exts[i].str[exts_pos[i] - 1];
163                 if (ce == c1 || ce == c2) {
164                     if (exts_pos[i] == 1)
165                         return i;
166                     exts_pos[i]--;
167                     match = 1;
168                 } else
169                     exts_pos[i] = 0;
170             }
171         }
172         if (!match)
173             return -1;
174     }
175
176     return -1;
177 }