Mercurial > hg > xmms-sid
comparison src/xs_stil.c @ 94:086681f70910
Start of re-write of STIL-support
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 10 Jan 2004 22:53:00 +0000 |
parents | 0d1df20745dd |
children | 2bc56809ec0b |
comparison
equal
deleted
inserted
replaced
93:63cf9b2ddadf | 94:086681f70910 |
---|---|
19 You should have received a copy of the GNU General Public License | 19 You should have received a copy of the GNU General Public License |
20 along with this program; if not, write to the Free Software | 20 along with this program; if not, write to the Free Software |
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
22 */ | 22 */ |
23 | 23 |
24 #include "xmms-sid.h" | 24 #include "xs_stil.h" |
25 #include <glib.h> | 25 #include "xs_support.h" |
26 #include "xs_config.h" | |
27 #include <stdlib.h> | |
26 #include <stdio.h> | 28 #include <stdio.h> |
29 #include <ctype.h> | |
30 #include <string.h> | |
31 | |
32 /* | |
33 * Pointer to database in memory | |
34 */ | |
35 static t_xs_stil_node *xs_stildb = NULL; | |
36 static t_xs_stil_node **xs_stildbi = NULL; | |
37 static gint xs_stildbn = 0; | |
38 | |
39 | |
40 /* | |
41 * Hash-database handling functions | |
42 */ | |
43 t_xs_stil_node *xs_db_node_new(void) | |
44 { | |
45 t_xs_stil_node *pResult; | |
46 | |
47 /* Allocate memory for new node */ | |
48 pResult = (t_xs_stil_node *) g_malloc0(sizeof(t_xs_stil_node)); | |
49 if (!pResult) return NULL; | |
50 | |
51 return pResult; | |
52 } | |
53 | |
54 | |
55 void xs_db_node_free(t_xs_stil_node *pNode) | |
56 { | |
57 if (pNode) | |
58 { | |
59 for (i = 0; i < pNode->nsubTunes; i++) | |
60 { | |
61 g_free(pNode->subTune[i].pName); | |
62 g_free(pNode->subTune[i].pTitle); | |
63 g_free(pNode->subTune[i].pArtist); | |
64 g_free(pNode->subTune[i].pComment); | |
65 } | |
66 | |
67 g_free(pNode->pcFilename); | |
68 g_free(pNode); | |
69 } | |
70 } | |
71 | |
72 | |
73 /* | |
74 * Insert given node to db linked list | |
75 */ | |
76 #define LPREV (pNode->pPrev) | |
77 #define LTHIS (pNode) | |
78 #define LNEXT (pNode->pNext) | |
79 | |
80 void xs_db_node_insert(t_xs_stil_node *pNode) | |
81 { | |
82 if (xs_stildb) | |
83 { | |
84 /* The first node's pPrev points to last node */ | |
85 LPREV = xs_stildb->pPrev; /* New node's prev = Previous last node */ | |
86 xs_stildb->pPrev->pNext = pNode; /* Previous last node's next = New node */ | |
87 xs_stildb->pPrev = pNode; /* New last node = New node */ | |
88 LNEXT = NULL; /* But next is NULL! */ | |
89 } else { | |
90 xs_stildb = pNode; /* First node ... */ | |
91 LPREV = pNode; /* ... it's also last */ | |
92 LNEXT = NULL; /* But next is NULL! */ | |
93 } | |
94 } | |
95 | |
96 | |
97 /* | |
98 * Compare two given MD5-hashes. | |
99 * Return: 0 if equal | |
100 * negative if testHash1 < testHash2 | |
101 * positive if testHash1 > testHash2 | |
102 */ | |
103 gint xs_db_cmphash(t_xs_md5hash testHash1, t_xs_md5hash testHash2) | |
104 { | |
105 register gint i, res = 0; | |
106 | |
107 /* Compute difference of hashes */ | |
108 for (i = 0; (i < XS_MD5HASH_LENGTH) && (!res); i++) | |
109 res = (testHash1[i] - testHash2[i]); | |
110 | |
111 return res; | |
112 } | |
113 | |
114 | |
115 /* | |
116 * Get song length from database | |
117 */ | |
118 t_xs_stil_node * xs_db_get(gchar *pcFilename) | |
119 { | |
120 gint iStartNode, iEndNode, iQNode, r, i; | |
121 gboolean iFound; | |
122 t_xs_stil_node *pResult; | |
123 | |
124 /* Check the database pointers */ | |
125 if (!xs_stildb || !xs_stildbi) | |
126 return NULL; | |
127 | |
128 /* Look-up via index using binary search */ | |
129 pResult = NULL; | |
130 iStartNode = 0; | |
131 iEndNode = (xs_stildbn - 1); | |
132 iQNode = (iEndNode / 2); | |
133 iFound = FALSE; | |
134 | |
135 while ((!iFound) && ((iEndNode - iStartNode) > 128)) | |
136 { | |
137 r = xs_db_cmphash(pHash, xs_stildbi[iQNode]->md5Hash); | |
138 if (r < 0) | |
139 { | |
140 /* Hash was in the <- LEFT side */ | |
141 iEndNode = iQNode; | |
142 iQNode = iStartNode + ((iEndNode - iStartNode) / 2); | |
143 } else | |
144 if (r > 0) | |
145 { | |
146 /* Hash was in the RIGHT -> side */ | |
147 iStartNode = iQNode; | |
148 iQNode = iStartNode + ((iEndNode - iStartNode) / 2); | |
149 } else | |
150 iFound = TRUE; | |
151 } | |
152 | |
153 /* If not found already */ | |
154 if (!iFound) | |
155 { | |
156 /* Search the are linearly */ | |
157 iFound = FALSE; | |
158 i = iStartNode; | |
159 while ((i <= iEndNode) && (!iFound)) | |
160 { | |
161 if (xs_db_cmphash(pHash, xs_stildbi[i]->md5Hash) == 0) | |
162 iFound = TRUE; | |
163 else | |
164 i++; | |
165 } | |
166 | |
167 /* Check the result */ | |
168 if (iFound) | |
169 pResult = xs_stildbi[i]; | |
170 | |
171 } else { | |
172 /* Found via binary search */ | |
173 pResult = xs_stildbi[iQNode]; | |
174 } | |
175 | |
176 | |
177 return pResult; | |
178 } | |
179 | |
180 | |
181 /* | |
182 * Read database to memory | |
183 */ | |
184 gint xs_stildb_read(gchar *dbFilename) | |
185 { | |
186 FILE *inFile; | |
187 gchar inLine[XS_BUFSIZE]; | |
188 guint lineNum, linePos; | |
189 gboolean iOK; | |
190 t_xs_stil_node *tmpNode; | |
191 | |
192 /* Try to open the file */ | |
193 if ((inFile = fopen(dbFilename, "ra")) == NULL) | |
194 { | |
195 XSERR("Could not open STILDB '%s'\n", dbFilename); | |
196 return -1; | |
197 } | |
198 | |
199 /* Read and parse the data */ | |
200 lineNum = 0; | |
201 | |
202 while (!feof(inFile)) | |
203 { | |
204 fgets(inLine, sizeof(inLine), inFile); | |
205 lineNum++; | |
206 | |
207 } /* while */ | |
208 | |
209 /* Close the file */ | |
210 fclose(inFile); | |
211 return 0; | |
212 } | |
213 | |
214 | |
215 /* | |
216 * Compare two nodes' hashes | |
217 */ | |
218 gint xs_db_cmp(const void *pNode1, const void *pNode2) | |
219 { | |
220 /* We assume here that we never ever get NULL-pointers or similar */ | |
221 return xs_db_cmphash((*(t_xs_stil_node **) pNode1)->md5Hash, | |
222 (*(t_xs_stil_node **) pNode2)->md5Hash); | |
223 } | |
224 | |
225 | |
226 /* | |
227 * Initialize the song-length system | |
228 */ | |
229 gint xs_songlen_init(void) | |
230 { | |
231 t_xs_stil_node *pCurr; | |
232 gint i; | |
233 | |
234 XSDEBUG("stildb_init()\n"); | |
235 | |
236 /* Read the database */ | |
237 if (!xs_cfg.songlenDBPath) | |
238 return -10; | |
239 | |
240 if (xs_db_read(xs_cfg.songlenDBPath) < 0) | |
241 return -9; | |
242 | |
243 XSDEBUG("indexing...\n"); | |
244 | |
245 /* Get size of db */ | |
246 pCurr = xs_stildb; | |
247 xs_stildbn = 0; | |
248 while (pCurr) | |
249 { | |
250 xs_stildbn++; | |
251 pCurr = pCurr->pNext; | |
252 } | |
253 | |
254 /* Check number of nodes */ | |
255 if (xs_stildbn > 0) | |
256 { | |
257 /* Allocate memory for index-table */ | |
258 xs_stildbi = (t_xs_stil_node **) g_malloc(sizeof(t_xs_stil_node *) * xs_stildbn); | |
259 if (!xs_stildbi) return -6; | |
260 | |
261 /* Get node-pointers to table */ | |
262 i = 0; | |
263 pCurr = xs_stildb; | |
264 while (pCurr) | |
265 { | |
266 xs_stildbi[i++] = pCurr; | |
267 pCurr = pCurr->pNext; | |
268 } | |
269 | |
270 /* Sort the indexes */ | |
271 qsort(xs_stildbi, xs_stildbn, sizeof(t_xs_stil_node *), xs_db_cmp); | |
272 } | |
273 | |
274 /* OK */ | |
275 XSDEBUG("init ok.\n"); | |
276 return 0; | |
277 } | |
278 | |
279 | |
280 /* | |
281 * Close song-length system | |
282 */ | |
283 void xs_stil_close(void) | |
284 { | |
285 t_xs_stil_node *pCurr, *pNext; | |
286 | |
287 /* Free the memory allocated for database */ | |
288 XSDEBUG("stildb_close()\n"); | |
289 pCurr = xs_stildb; | |
290 while (pCurr) | |
291 { | |
292 pNext = pCurr->pNext; | |
293 xs_db_node_free(pCurr); | |
294 pCurr = pNext; | |
295 } | |
296 | |
297 xs_stildb = NULL; | |
298 | |
299 /* Free memory allocated for indexes */ | |
300 if (xs_stildbi) | |
301 { | |
302 g_free(xs_stildbi); | |
303 xs_stildbi = NULL; | |
304 } | |
305 } | |
306 | |
307 | |
308 /* | |
309 * Get STIL information | |
310 */ | |
311 t_xs_stil_node * xs_stil_get(gchar *pcFilename) | |
312 { | |
313 t_xs_stil_node *pResult; | |
314 | |
315 return pResult; | |
316 } |