Mercurial > hg > xmms-sid
comparison src/xs_length.c @ 227:92bad4c7b998
Improved modularization of STIL and song-length database subsystems.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sun, 19 Dec 2004 16:53:05 +0000 |
parents | 16e3b2446a73 |
children | 608f31f6c095 |
comparison
equal
deleted
inserted
replaced
226:858c09f59011 | 227:92bad4c7b998 |
---|---|
19 along with this program; if not, write to the Free Software | 19 along with this program; if not, write to the Free Software |
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21 */ | 21 */ |
22 #include "xs_length.h" | 22 #include "xs_length.h" |
23 #include "xs_support.h" | 23 #include "xs_support.h" |
24 #include "xs_config.h" | |
25 #include <stdio.h> | 24 #include <stdio.h> |
26 #include <stdlib.h> | 25 #include <stdlib.h> |
27 #include <ctype.h> | 26 #include <ctype.h> |
28 #include <string.h> | 27 #include <string.h> |
29 | 28 |
30 | 29 |
31 /* | 30 /* Database handling functions |
32 * Pointer to database in memory | 31 */ |
33 */ | 32 static t_xs_sldb_node *xs_sldb_node_new(void) |
34 static t_xs_sldb_node *xs_sldb = NULL; | |
35 static t_xs_sldb_node **xs_sldbi = NULL; | |
36 static gint xs_sldbn = 0; | |
37 | |
38 | |
39 /* | |
40 * Hash-database handling functions | |
41 */ | |
42 t_xs_sldb_node *xs_sldb_node_new(void) | |
43 { | 33 { |
44 t_xs_sldb_node *pResult; | 34 t_xs_sldb_node *pResult; |
45 | 35 |
46 /* Allocate memory for new node */ | 36 /* Allocate memory for new node */ |
47 pResult = (t_xs_sldb_node *) g_malloc0(sizeof(t_xs_sldb_node)); | 37 pResult = (t_xs_sldb_node *) g_malloc0(sizeof(t_xs_sldb_node)); |
49 | 39 |
50 return pResult; | 40 return pResult; |
51 } | 41 } |
52 | 42 |
53 | 43 |
54 void xs_sldb_node_free(t_xs_sldb_node *pNode) | 44 static void xs_sldb_node_free(t_xs_sldb_node *pNode) |
55 { | 45 { |
56 if (pNode) g_free(pNode); | 46 if (pNode) |
57 } | 47 { |
58 | 48 /* Nothing much to do here ... */ |
59 | 49 g_free(pNode); |
60 /* | 50 } |
61 * Insert given node to db linked list | 51 } |
62 */ | 52 |
63 #define LPREV (pNode->pPrev) | 53 |
64 #define LTHIS (pNode) | 54 /* Insert given node to db linked list |
65 #define LNEXT (pNode->pNext) | 55 */ |
66 | 56 static void xs_sldb_node_insert(t_xs_sldb *db, t_xs_sldb_node *pNode) |
67 void xs_sldb_node_insert(t_xs_sldb_node *pNode) | 57 { |
68 { | 58 assert(db); |
69 if (xs_sldb) | 59 |
60 if (db->pNodes) | |
70 { | 61 { |
71 /* The first node's pPrev points to last node */ | 62 /* The first node's pPrev points to last node */ |
72 LPREV = xs_sldb->pPrev; /* New node's prev = Previous last node */ | 63 LPREV = db->pNodes->pPrev; /* New node's prev = Previous last node */ |
73 xs_sldb->pPrev->pNext = pNode; /* Previous last node's next = New node */ | 64 db->pNodes->pPrev->pNext = pNode; /* Previous last node's next = New node */ |
74 xs_sldb->pPrev = pNode; /* New last node = New node */ | 65 db->pNodes->pPrev = pNode; /* New last node = New node */ |
75 LNEXT = NULL; /* But next is NULL! */ | 66 LNEXT = NULL; /* But next is NULL! */ |
76 } else { | 67 } else { |
77 xs_sldb = pNode; /* First node ... */ | 68 db->pNodes = pNode; /* First node ... */ |
78 LPREV = pNode; /* ... it's also last */ | 69 LPREV = pNode; /* ... it's also last */ |
79 LNEXT = NULL; /* But next is NULL! */ | 70 LNEXT = NULL; /* But next is NULL! */ |
80 } | 71 } |
81 } | 72 } |
82 | 73 |
83 | 74 |
84 /* | 75 /* Parses a time-entry in SLDB format |
85 * Compare two given MD5-hashes. | 76 */ |
86 * Return: 0 if equal | 77 static gint32 xs_sldb_gettime(gchar *pcStr, int *piPos) |
87 * negative if testHash1 < testHash2 | |
88 * positive if testHash1 > testHash2 | |
89 */ | |
90 gint xs_sldb_cmphash(t_xs_md5hash testHash1, t_xs_md5hash testHash2) | |
91 { | |
92 register gint i, res = 0; | |
93 | |
94 /* Compute difference of hashes */ | |
95 for (i = 0; (i < XS_MD5HASH_LENGTH) && (!res); i++) | |
96 res = (testHash1[i] - testHash2[i]); | |
97 | |
98 return res; | |
99 } | |
100 | |
101 | |
102 /* | |
103 * Get song length from database | |
104 */ | |
105 t_xs_sldb_node * xs_sldb_get(t_xs_md5hash pHash) | |
106 { | |
107 gint iStartNode, iEndNode, iQNode, r, i; | |
108 gboolean iFound; | |
109 t_xs_sldb_node *pResult; | |
110 | |
111 /* Check the database pointers */ | |
112 if (!xs_sldb || !xs_sldbi) | |
113 return NULL; | |
114 | |
115 /* Look-up via index using binary search */ | |
116 pResult = NULL; | |
117 iStartNode = 0; | |
118 iEndNode = (xs_sldbn - 1); | |
119 iQNode = (iEndNode / 2); | |
120 iFound = FALSE; | |
121 | |
122 while ((!iFound) && ((iEndNode - iStartNode) > 128)) | |
123 { | |
124 r = xs_sldb_cmphash(pHash, xs_sldbi[iQNode]->md5Hash); | |
125 if (r < 0) | |
126 { | |
127 /* Hash was in the <- LEFT side */ | |
128 iEndNode = iQNode; | |
129 iQNode = iStartNode + ((iEndNode - iStartNode) / 2); | |
130 } else | |
131 if (r > 0) | |
132 { | |
133 /* Hash was in the RIGHT -> side */ | |
134 iStartNode = iQNode; | |
135 iQNode = iStartNode + ((iEndNode - iStartNode) / 2); | |
136 } else | |
137 iFound = TRUE; | |
138 } | |
139 | |
140 /* If not found already */ | |
141 if (!iFound) | |
142 { | |
143 /* Search the are linearly */ | |
144 iFound = FALSE; | |
145 i = iStartNode; | |
146 while ((i <= iEndNode) && (!iFound)) | |
147 { | |
148 if (xs_sldb_cmphash(pHash, xs_sldbi[i]->md5Hash) == 0) | |
149 iFound = TRUE; | |
150 else | |
151 i++; | |
152 } | |
153 | |
154 /* Check the result */ | |
155 if (iFound) | |
156 pResult = xs_sldbi[i]; | |
157 | |
158 } else { | |
159 /* Found via binary search */ | |
160 pResult = xs_sldbi[iQNode]; | |
161 } | |
162 | |
163 | |
164 return pResult; | |
165 } | |
166 | |
167 | |
168 /* | |
169 * Parses a time-entry in SLDB format | |
170 */ | |
171 gint32 xs_gettime(gchar *pcStr, int *piPos) | |
172 { | 78 { |
173 gint32 iResult, iTemp; | 79 gint32 iResult, iTemp; |
174 | 80 |
175 /* Check if it starts with a digit */ | 81 /* Check if it starts with a digit */ |
176 if (isdigit(pcStr[*piPos])) | 82 if (isdigit(pcStr[*piPos])) |
202 | 108 |
203 return iResult; | 109 return iResult; |
204 } | 110 } |
205 | 111 |
206 | 112 |
207 /* | 113 /* Read database to memory |
208 * Read database to memory | 114 */ |
209 */ | 115 gint xs_sldb_read(t_xs_sldb *db, gchar *dbFilename) |
210 gint xs_sldb_read(gchar *dbFilename) | |
211 { | 116 { |
212 FILE *inFile; | 117 FILE *inFile; |
213 gchar inLine[XS_BUFSIZE]; | 118 gchar inLine[XS_BUFSIZE]; |
214 guint lineNum, linePos; | 119 guint lineNum, linePos; |
215 gboolean iOK; | 120 gboolean iOK; |
216 t_xs_sldb_node *tmpNode; | 121 t_xs_sldb_node *tmpNode; |
122 assert(db); | |
217 | 123 |
218 /* Try to open the file */ | 124 /* Try to open the file */ |
219 if ((inFile = fopen(dbFilename, "ra")) == NULL) | 125 if ((inFile = fopen(dbFilename, "ra")) == NULL) |
220 { | 126 { |
221 XSERR("Could not open SongLengthDB '%s'\n", dbFilename); | 127 XSERR("Could not open SongLengthDB '%s'\n", dbFilename); |
282 xs_findnext(inLine, &linePos); | 188 xs_findnext(inLine, &linePos); |
283 | 189 |
284 if (tmpNode->nLengths < XS_STIL_MAXENTRY) | 190 if (tmpNode->nLengths < XS_STIL_MAXENTRY) |
285 { | 191 { |
286 tmpNode->sLengths[tmpNode->nLengths] = | 192 tmpNode->sLengths[tmpNode->nLengths] = |
287 xs_gettime(inLine, &linePos); | 193 xs_sldb_gettime(inLine, &linePos); |
288 tmpNode->nLengths++; | 194 tmpNode->nLengths++; |
289 } else | 195 } else |
290 iOK = FALSE; | 196 iOK = FALSE; |
291 } | 197 } |
292 | 198 |
293 /* Add an node to db in memory */ | 199 /* Add an node to db in memory */ |
294 if (iOK) | 200 if (iOK) |
295 xs_sldb_node_insert(tmpNode); | 201 xs_sldb_node_insert(db, tmpNode); |
296 else | 202 else |
297 xs_sldb_node_free(tmpNode); | 203 xs_sldb_node_free(tmpNode); |
298 } | 204 } |
299 } | 205 } |
300 } | 206 } |
312 | 218 |
313 return 0; | 219 return 0; |
314 } | 220 } |
315 | 221 |
316 | 222 |
317 /* | 223 /* Compare two given MD5-hashes. |
318 * Compare two nodes' hashes | 224 * Return: 0 if equal |
319 */ | 225 * negative if testHash1 < testHash2 |
320 gint xs_sldb_cmp(const void *pNode1, const void *pNode2) | 226 * positive if testHash1 > testHash2 |
227 */ | |
228 static gint xs_sldb_cmphash(t_xs_md5hash testHash1, t_xs_md5hash testHash2) | |
229 { | |
230 register gint i, res = 0; | |
231 | |
232 /* Compute difference of hashes */ | |
233 for (i = 0; (i < XS_MD5HASH_LENGTH) && (!res); i++) | |
234 res = (testHash1[i] - testHash2[i]); | |
235 | |
236 return res; | |
237 } | |
238 | |
239 | |
240 /* Get node from db index via binary search | |
241 */ | |
242 static t_xs_sldb_node * xs_sldb_get_node(t_xs_sldb *db, t_xs_md5hash pHash) | |
243 { | |
244 gint iStartNode, iEndNode, iQNode, r, i; | |
245 gboolean iFound; | |
246 t_xs_sldb_node *pResult; | |
247 | |
248 /* Check the database pointers */ | |
249 if (!db || !db->pNodes || !db->ppIndex) | |
250 return NULL; | |
251 | |
252 /* Look-up via index using binary search */ | |
253 pResult = NULL; | |
254 iStartNode = 0; | |
255 iEndNode = (db->n - 1); | |
256 iQNode = (iEndNode / 2); | |
257 iFound = FALSE; | |
258 | |
259 while ((!iFound) && ((iEndNode - iStartNode) > 128)) | |
260 { | |
261 r = xs_sldb_cmphash(pHash, db->ppIndex[iQNode]->md5Hash); | |
262 if (r < 0) | |
263 { | |
264 /* Hash was in the <- LEFT side */ | |
265 iEndNode = iQNode; | |
266 iQNode = iStartNode + ((iEndNode - iStartNode) / 2); | |
267 } else | |
268 if (r > 0) | |
269 { | |
270 /* Hash was in the RIGHT -> side */ | |
271 iStartNode = iQNode; | |
272 iQNode = iStartNode + ((iEndNode - iStartNode) / 2); | |
273 } else | |
274 iFound = TRUE; | |
275 } | |
276 | |
277 /* If not found already */ | |
278 if (!iFound) | |
279 { | |
280 /* Search the are linearly */ | |
281 iFound = FALSE; | |
282 i = iStartNode; | |
283 while ((i <= iEndNode) && (!iFound)) | |
284 { | |
285 if (xs_sldb_cmphash(pHash, db->ppIndex[i]->md5Hash) == 0) | |
286 iFound = TRUE; | |
287 else | |
288 i++; | |
289 } | |
290 | |
291 /* Check the result */ | |
292 if (iFound) | |
293 pResult = db->ppIndex[i]; | |
294 | |
295 } else { | |
296 /* Found via binary search */ | |
297 pResult = db->ppIndex[iQNode]; | |
298 } | |
299 | |
300 return pResult; | |
301 } | |
302 | |
303 | |
304 /* Compare two nodes | |
305 */ | |
306 static gint xs_sldb_cmp(const void *pNode1, const void *pNode2) | |
321 { | 307 { |
322 /* We assume here that we never ever get NULL-pointers or similar */ | 308 /* We assume here that we never ever get NULL-pointers or similar */ |
323 return xs_sldb_cmphash((*(t_xs_sldb_node **) pNode1)->md5Hash, | 309 return xs_sldb_cmphash((*(t_xs_sldb_node **) pNode1)->md5Hash, |
324 (*(t_xs_sldb_node **) pNode2)->md5Hash); | 310 (*(t_xs_sldb_node **) pNode2)->md5Hash); |
325 } | 311 } |
326 | 312 |
327 | 313 |
328 /* | 314 /* (Re)create index |
329 * Initialize the song-length system | 315 */ |
330 */ | 316 gint xs_sldb_index(t_xs_sldb *db) |
331 gint xs_songlen_init(void) | |
332 { | 317 { |
333 t_xs_sldb_node *pCurr; | 318 t_xs_sldb_node *pCurr; |
334 gint i; | 319 gint i; |
335 | 320 assert(db); |
336 XSDEBUG("sldb_init()\n"); | 321 |
337 | 322 /* Free old index */ |
338 /* Read the database */ | 323 if (db->ppIndex) |
339 if (!xs_cfg.songlenDBPath) | 324 { |
340 return -10; | 325 g_free(db->ppIndex); |
341 | 326 db->ppIndex = NULL; |
342 if (xs_sldb_read(xs_cfg.songlenDBPath) < 0) | 327 } |
343 return -9; | 328 |
344 | |
345 XSDEBUG("indexing...\n"); | |
346 | |
347 /* Get size of db */ | 329 /* Get size of db */ |
348 pCurr = xs_sldb; | 330 pCurr = db->pNodes; |
349 xs_sldbn = 0; | 331 db->n = 0; |
350 while (pCurr) | 332 while (pCurr) |
351 { | 333 { |
352 xs_sldbn++; | 334 db->n++; |
353 pCurr = pCurr->pNext; | 335 pCurr = pCurr->pNext; |
354 } | 336 } |
355 | 337 |
356 /* Check number of nodes */ | 338 /* Check number of nodes */ |
357 if (xs_sldbn > 0) | 339 if (db->n > 0) |
358 { | 340 { |
359 /* Allocate memory for index-table */ | 341 /* Allocate memory for index-table */ |
360 xs_sldbi = (t_xs_sldb_node **) g_malloc(sizeof(t_xs_sldb_node *) * xs_sldbn); | 342 db->ppIndex = (t_xs_sldb_node **) g_malloc(sizeof(t_xs_sldb_node *) * db->n); |
361 if (!xs_sldbi) return -6; | 343 if (!db->ppIndex) return -1; |
362 | 344 |
363 /* Get node-pointers to table */ | 345 /* Get node-pointers to table */ |
364 i = 0; | 346 i = 0; |
365 pCurr = xs_sldb; | 347 pCurr = db->pNodes; |
366 while (pCurr) | 348 while (pCurr && (i < db->n)) |
367 { | 349 { |
368 xs_sldbi[i++] = pCurr; | 350 db->ppIndex[i++] = pCurr; |
369 pCurr = pCurr->pNext; | 351 pCurr = pCurr->pNext; |
370 } | 352 } |
371 | 353 |
372 /* Sort the indexes */ | 354 /* Sort the indexes */ |
373 qsort(xs_sldbi, xs_sldbn, sizeof(t_xs_sldb_node *), xs_sldb_cmp); | 355 qsort(db->ppIndex, db->n, sizeof(t_xs_sldb_node *), xs_sldb_cmp); |
374 } | 356 } |
375 | 357 |
376 /* OK */ | |
377 XSDEBUG("init ok.\n"); | |
378 return 0; | 358 return 0; |
379 } | 359 } |
380 | 360 |
381 | 361 |
382 /* | 362 /* Free a given song-length database |
383 * Close song-length system | 363 */ |
384 */ | 364 void xs_sldb_free(t_xs_sldb *db) |
385 void xs_songlen_close(void) | |
386 { | 365 { |
387 t_xs_sldb_node *pCurr, *pNext; | 366 t_xs_sldb_node *pCurr, *pNext; |
388 | 367 |
389 /* Free the memory allocated for database */ | 368 if (!db) return; |
390 XSDEBUG("sldb_close()\n"); | 369 |
391 pCurr = xs_sldb; | 370 /* Free the memory allocated for nodes */ |
371 pCurr = db->pNodes; | |
392 while (pCurr) | 372 while (pCurr) |
393 { | 373 { |
394 pNext = pCurr->pNext; | 374 pNext = pCurr->pNext; |
395 xs_sldb_node_free(pCurr); | 375 xs_sldb_node_free(pCurr); |
396 pCurr = pNext; | 376 pCurr = pNext; |
397 } | 377 } |
398 | 378 |
399 xs_sldb = NULL; | 379 db->pNodes = NULL; |
400 | 380 |
401 /* Free memory allocated for indexes */ | 381 /* Free memory allocated for index */ |
402 if (xs_sldbi) | 382 if (db->ppIndex) |
403 { | 383 { |
404 g_free(xs_sldbi); | 384 g_free(db->ppIndex); |
405 xs_sldbi = NULL; | 385 db->ppIndex = NULL; |
406 } | 386 } |
407 } | 387 |
408 | 388 /* Free structure */ |
409 | 389 db->n = 0; |
410 /* | 390 g_free(db); |
411 * Compute md5hash of given SID-file | 391 } |
392 | |
393 | |
394 /* Compute md5hash of given SID-file | |
412 */ | 395 */ |
413 typedef struct { | 396 typedef struct { |
414 gchar magicID[4]; /* "PSID" magic identifier */ | 397 gchar magicID[4]; /* "PSID" magic identifier */ |
415 guint16 version, /* Version number */ | 398 guint16 version, /* Version number */ |
416 dataOffset, /* Start of actual c64 data in file */ | 399 dataOffset, /* Start of actual c64 data in file */ |
432 pageLength; | 415 pageLength; |
433 guint16 reserved; | 416 guint16 reserved; |
434 } t_xs_psidv2_header; | 417 } t_xs_psidv2_header; |
435 | 418 |
436 | 419 |
437 guint16 rd_be16(FILE *f) | 420 static gint xs_get_sid_hash(gchar *pcFilename, t_xs_md5hash hash) |
438 { | |
439 return (((guint16) fgetc(f)) << 8) | | |
440 ((guint16) fgetc(f)); | |
441 } | |
442 | |
443 | |
444 guint32 rd_be32(FILE *f) | |
445 { | |
446 return (((guint32) fgetc(f)) << 24) | | |
447 (((guint32) fgetc(f)) << 16) | | |
448 (((guint32) fgetc(f)) << 8) | | |
449 ((guint32) fgetc(f)); | |
450 } | |
451 | |
452 | |
453 gint rd_str(FILE *f, gchar *s, gint l) | |
454 { | |
455 return fread(s, sizeof(gchar), l, f); | |
456 } | |
457 | |
458 #define MAX_MEMBUF (80*1024) | |
459 | |
460 gint xs_get_sid_hash(gchar *pcFilename, t_xs_md5hash hash) | |
461 { | 421 { |
462 FILE *inFile; | 422 FILE *inFile; |
463 t_xs_md5state inState; | 423 t_xs_md5state inState; |
464 t_xs_psidv1_header psidH; | 424 t_xs_psidv1_header psidH; |
465 t_xs_psidv2_header psidH2; | 425 t_xs_psidv2_header psidH2; |
466 guint8 songData[MAX_MEMBUF+1], ib8[2], i8; | 426 #ifdef XS_SIDBUF_DYNAMIC |
427 guint8 *songData; | |
428 #else | |
429 guint8 songData[XS_SIDBUF_SIZE]; | |
430 #endif | |
431 guint8 ib8[2], i8; | |
467 gint iIndex, iRes; | 432 gint iIndex, iRes; |
468 | |
469 | 433 |
470 /* Try to open the file */ | 434 /* Try to open the file */ |
471 if ((inFile = fopen(pcFilename, "rb")) == NULL) | 435 if ((inFile = fopen(pcFilename, "rb")) == NULL) |
472 return -1; | 436 return -1; |
473 | 437 |
474 /* Read PSID header in */ | 438 /* Read PSID header in */ |
475 rd_str(inFile, psidH.magicID, sizeof(psidH.magicID)); | 439 xs_rd_str(inFile, psidH.magicID, sizeof(psidH.magicID)); |
476 if ((psidH.magicID[0] != 'P') || (psidH.magicID[1] != 'S') || | 440 if ((psidH.magicID[0] != 'P') || (psidH.magicID[1] != 'S') || |
477 (psidH.magicID[2] != 'I') || (psidH.magicID[3] != 'D')) | 441 (psidH.magicID[2] != 'I') || (psidH.magicID[3] != 'D')) |
442 { | |
443 fclose(inFile); | |
478 return -2; | 444 return -2; |
479 | 445 } |
480 psidH.version = rd_be16(inFile); | 446 |
481 psidH.dataOffset = rd_be16(inFile); | 447 psidH.version = xs_rd_be16(inFile); |
482 psidH.loadAddress = rd_be16(inFile); | 448 psidH.dataOffset = xs_rd_be16(inFile); |
483 psidH.initAddress = rd_be16(inFile); | 449 psidH.loadAddress = xs_rd_be16(inFile); |
484 psidH.playAddress = rd_be16(inFile); | 450 psidH.initAddress = xs_rd_be16(inFile); |
485 psidH.nSongs = rd_be16(inFile); | 451 psidH.playAddress = xs_rd_be16(inFile); |
486 psidH.startSong = rd_be16(inFile); | 452 psidH.nSongs = xs_rd_be16(inFile); |
487 psidH.speed = rd_be32(inFile); | 453 psidH.startSong = xs_rd_be16(inFile); |
488 | 454 psidH.speed = xs_rd_be32(inFile); |
489 rd_str(inFile, psidH.sidName, sizeof(psidH.sidName)); | 455 |
490 rd_str(inFile, psidH.sidAuthor, sizeof(psidH.sidAuthor)); | 456 xs_rd_str(inFile, psidH.sidName, sizeof(psidH.sidName)); |
491 rd_str(inFile, psidH.sidCopyright, sizeof(psidH.sidCopyright)); | 457 xs_rd_str(inFile, psidH.sidAuthor, sizeof(psidH.sidAuthor)); |
458 xs_rd_str(inFile, psidH.sidCopyright, sizeof(psidH.sidCopyright)); | |
492 | 459 |
493 /* Check if we need to load PSIDv2NG header ... */ | 460 /* Check if we need to load PSIDv2NG header ... */ |
494 if (psidH.version == 2) | 461 if (psidH.version == 2) |
495 { | 462 { |
496 /* Yes, we need to */ | 463 /* Yes, we need to */ |
497 psidH2.flags = rd_be16(inFile); | 464 psidH2.flags = xs_rd_be16(inFile); |
498 psidH2.startPage = fgetc(inFile); | 465 psidH2.startPage = fgetc(inFile); |
499 psidH2.pageLength = fgetc(inFile); | 466 psidH2.pageLength = fgetc(inFile); |
500 psidH2.reserved = rd_be16(inFile); | 467 psidH2.reserved = xs_rd_be16(inFile); |
501 } | 468 } |
502 | 469 |
470 #ifdef XS_SIDBUF_DYNAMIC | |
471 /* Allocate buffer */ | |
472 songData = (guint8 *) g_malloc(XS_SIDBUF_SIZE * sizeof(guint8)); | |
473 if (!songData) | |
474 { | |
475 fclose(inFile); | |
476 return -3; | |
477 } | |
478 #endif | |
479 | |
503 /* Read data to buffer */ | 480 /* Read data to buffer */ |
504 iRes = fread(songData, sizeof(guint8), MAX_MEMBUF, inFile); | 481 iRes = fread(songData, sizeof(guint8), XS_SIDBUF_SIZE, inFile); |
505 fclose(inFile); | 482 fclose(inFile); |
506 | 483 |
507 /* Initialize and start MD5-hash calculation */ | 484 /* Initialize and start MD5-hash calculation */ |
508 xs_md5_init(&inState); | 485 xs_md5_init(&inState); |
509 if (psidH.loadAddress == 0) | 486 if (psidH.loadAddress == 0) |
510 /* COULD SOMEONE EXPLAIN WHY DO WE NEED THIS +2 STRIP???? */ | 487 { |
488 /* Strip load address (2 first bytes) */ | |
511 xs_md5_append(&inState, &songData[2], iRes-2); | 489 xs_md5_append(&inState, &songData[2], iRes-2); |
512 else | 490 } else { |
491 /* Append "as is" */ | |
513 xs_md5_append(&inState, songData, iRes); | 492 xs_md5_append(&inState, songData, iRes); |
493 } | |
494 | |
495 | |
496 #ifdef XS_SIDBUF_DYNAMIC | |
497 /* Free buffer */ | |
498 g_free(songData); | |
499 #endif | |
514 | 500 |
515 /* Append header data to hash */ | 501 /* Append header data to hash */ |
516 #define XSADDHASH(QDATAB) { ib8[0] = (QDATAB & 0xff); ib8[1] = (QDATAB >> 8); xs_md5_append(&inState, (guint8 *) &ib8, sizeof(ib8)); } | 502 #define XSADDHASH(QDATAB) { ib8[0] = (QDATAB & 0xff); ib8[1] = (QDATAB >> 8); xs_md5_append(&inState, (guint8 *) &ib8, sizeof(ib8)); } |
517 | 503 |
518 XSADDHASH(psidH.initAddress) | 504 XSADDHASH(psidH.initAddress) |
550 | 536 |
551 return 0; | 537 return 0; |
552 } | 538 } |
553 | 539 |
554 | 540 |
555 /* | 541 /* Get song lengths |
556 * Get song lengths | 542 */ |
557 */ | 543 t_xs_sldb_node * xs_sldb_get(t_xs_sldb *db, gchar *pcFilename) |
558 t_xs_sldb_node * xs_songlen_get(gchar *pcFilename) | |
559 { | 544 { |
560 t_xs_sldb_node *pResult; | 545 t_xs_sldb_node *pResult; |
561 t_xs_md5hash dbHash; | 546 t_xs_md5hash dbHash; |
562 | 547 |
563 pResult = NULL; | 548 /* Get the hash and then look up from db */ |
564 | 549 if (xs_get_sid_hash(pcFilename, dbHash) == 0) |
565 if (xs_cfg.songlenDBEnable) | 550 pResult = xs_sldb_get_node(db, dbHash); |
566 { | 551 else |
567 /* Get the hash and then look up from db */ | 552 pResult = NULL; |
568 if (xs_get_sid_hash(pcFilename, dbHash) == 0) | 553 |
569 { | |
570 pResult = xs_sldb_get(dbHash); | |
571 } | |
572 } | |
573 | |
574 return pResult; | 554 return pResult; |
575 } | 555 } |