Mercurial > hg > xmms-sid
comparison src/xs_length.c @ 14:f5d82424b0ed
Made song-length database support FINALLY work!
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 04 Jun 2003 18:00:03 +0000 |
parents | 4bb09e405eab |
children | ac2972a7ccd5 |
comparison
equal
deleted
inserted
replaced
13:7e664541ea36 | 14:f5d82424b0ed |
---|---|
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 | 22 |
23 #include "xmms-sid.h" | 23 #include "xmms-sid.h" |
24 #include "xs_support.h" | |
24 #include "xs_length.h" | 25 #include "xs_length.h" |
26 #include "xs_config.h" | |
27 #include "xs_md5.h" | |
25 #include <stdlib.h> | 28 #include <stdlib.h> |
26 #include <stdio.h> | 29 #include <stdio.h> |
27 #include <ctype.h> | 30 #include <ctype.h> |
28 #include <string.h> | 31 #include <string.h> |
29 | 32 |
33 | |
30 /* | 34 /* |
31 * Pointer to database in memory | 35 * Pointer to database in memory |
32 */ | 36 */ |
33 static t_xs_dbentry *xs_database = NULL; | 37 static t_xs_dbentry *xs_database = NULL, *xs_dblast = NULL; |
38 static t_xs_dbentry **xs_dbindex = NULL; | |
39 static gint xs_dbnodes = 0; | |
40 | |
41 | |
42 /* | |
43 * Hash-database handling functions | |
44 */ | |
45 t_xs_dbentry *xs_db_node_new(void) | |
46 { | |
47 t_xs_dbentry *pResult; | |
48 | |
49 /* Allocate memory for new node */ | |
50 pResult = (t_xs_dbentry *) calloc(1, sizeof(t_xs_dbentry)); | |
51 if (pResult == NULL) return NULL; | |
52 | |
53 return pResult; | |
54 } | |
55 | |
56 | |
57 void xs_db_node_free(t_xs_dbentry *pNode) | |
58 { | |
59 if (pNode) free(pNode); | |
60 } | |
61 | |
62 | |
63 /* | |
64 * Insert given node to db linked list | |
65 */ | |
66 void xs_db_node_insert(t_xs_dbentry *pNode) | |
67 { | |
68 if (xs_dblast) | |
69 { | |
70 xs_dblast->pNext = pNode; | |
71 xs_dblast = pNode; | |
72 } else { | |
73 xs_dblast = xs_database = pNode; | |
74 pNode->pNext = NULL; | |
75 } | |
76 } | |
77 | |
78 | |
79 /* | |
80 * Compare two given MD5-hashes. | |
81 * Return: 0 if equal | |
82 * negative if testHash1 < testHash2 | |
83 * positive if testHash1 > testHash2 | |
84 */ | |
85 gint xs_db_cmphash(t_xs_md5hash testHash1, t_xs_md5hash testHash2) | |
86 { | |
87 register gint i, res = 0; | |
88 | |
89 /* Compute difference of hashes */ | |
90 for (i = 0; (i < XS_MD5HASH_LENGTH) && (!res); i++) | |
91 res = (testHash1[i] - testHash2[i]); | |
92 | |
93 return res; | |
94 } | |
95 | |
96 | |
97 /* | |
98 * Get song length from database | |
99 */ | |
100 t_xs_dbentry * xs_db_get(t_xs_md5hash pHash) | |
101 { | |
102 gint iStartNode, iEndNode, iQNode, iFound, r, i; | |
103 t_xs_dbentry *pResult; | |
104 | |
105 /* Check the database pointers */ | |
106 if ((xs_database == NULL) || (xs_dbindex == NULL)) | |
107 return NULL; | |
108 | |
109 /* Look-up via index using binary search */ | |
110 pResult = NULL; | |
111 iStartNode = 0; | |
112 iEndNode = (xs_dbnodes - 1); | |
113 iQNode = (iEndNode / 2); | |
114 iFound = 0; | |
115 | |
116 while ((!iFound) && ((iEndNode - iStartNode) > 128)) | |
117 { | |
118 fprintf(stderr, "["); | |
119 fprinth(stderr, xs_dbindex[iQNode]->md5Hash); | |
120 r = xs_db_cmphash(pHash, xs_dbindex[iQNode]->md5Hash); | |
121 fprintf(stderr, "] = %i\n", r); | |
122 if (r < 0) | |
123 { | |
124 /* Hash was in the <- LEFT side */ | |
125 iEndNode = iQNode; | |
126 iQNode = iStartNode + ((iEndNode - iStartNode) / 2); | |
127 } else | |
128 if (r > 0) | |
129 { | |
130 /* Hash was in the RIGHT -> side */ | |
131 iStartNode = iQNode; | |
132 iQNode = iStartNode + ((iEndNode - iStartNode) / 2); | |
133 } else | |
134 iFound = 1; | |
135 } | |
136 | |
137 /* If not found already */ | |
138 if (!iFound) | |
139 { | |
140 /* Search the are linearly */ | |
141 iFound = 0; | |
142 i = iStartNode; | |
143 while ((i <= iEndNode) && (!iFound)) | |
144 { | |
145 if (xs_db_cmphash(pHash, xs_dbindex[i]->md5Hash) == 0) | |
146 iFound = 1; | |
147 else | |
148 i++; | |
149 } | |
150 | |
151 /* Check the result */ | |
152 if (iFound) | |
153 pResult = xs_dbindex[i]; | |
154 | |
155 } else { | |
156 /* Found via binary search */ | |
157 pResult = xs_dbindex[iEndNode]; | |
158 } | |
159 | |
160 | |
161 return pResult; | |
162 } | |
34 | 163 |
35 | 164 |
36 /* | 165 /* |
37 * Parses a time-entry in SLDB format | 166 * Parses a time-entry in SLDB format |
38 */ | 167 */ |
39 long int xs_gettime(char *pcStr, int *piPos) | 168 gint32 xs_gettime(gchar *pcStr, int *piPos) |
40 { | 169 { |
41 long int iResult; | 170 gint32 iResult, iTemp; |
42 int iTemp; | |
43 char chTempBuf[16]; | |
44 | 171 |
45 /* Check if it starts with a digit */ | 172 /* Check if it starts with a digit */ |
46 if (isdigit(pcStr[*piPos])) | 173 if (isdigit(pcStr[*piPos])) |
47 { | 174 { |
48 /* Get minutes-field */ | 175 /* Get minutes-field */ |
49 iTemp = *piPos; | 176 iResult = 0; |
50 xs_findnum(pcStr, piPos); | 177 while (isdigit(pcStr[*piPos])) |
51 | 178 iResult = (iResult * 10) + (pcStr[(*piPos)++] - '0'); |
52 strncpy(chTempBuf, &pcStr[iTemp], (*piPos - iTemp)); | 179 |
53 chTempBuf[*piPos - iTemp] = 0; | 180 iResult *= 60; |
54 | |
55 iResult = (atol(chTempBuf) * 60); | |
56 | 181 |
57 /* Check the field separator char */ | 182 /* Check the field separator char */ |
58 if (pcStr[*piPos] == ':') | 183 if (pcStr[*piPos] == ':') |
59 { | 184 { |
60 /* Get seconds-field */ | 185 /* Get seconds-field */ |
61 (*piPos)++; | 186 (*piPos)++; |
62 iTemp = *piPos; | 187 iTemp = 0; |
63 xs_findnum(pcStr, piPos); | 188 while (isdigit(pcStr[*piPos])) |
64 | 189 iTemp = (iTemp * 10) + (pcStr[(*piPos)++] - '0'); |
65 strncpy(chTempBuf, &pcStr[iTemp], (*piPos - iTemp)); | 190 |
66 chTempBuf[*piPos - iTemp] = 0; | 191 iResult += iTemp; |
67 | |
68 iResult += atol(chTempBuf); | |
69 | |
70 } else | 192 } else |
71 iResult = -2; | 193 iResult = -2; |
72 } else | 194 } else |
73 iResult = -1; | 195 iResult = -1; |
74 | 196 |
78 return iResult; | 200 return iResult; |
79 } | 201 } |
80 | 202 |
81 | 203 |
82 /* | 204 /* |
83 * Initialize, read database to memory | 205 * Read database to memory |
84 */ | 206 */ |
85 gint xs_db_initialize(gchar *pcFilename) | 207 gint xs_db_read(gchar *dbFilename, t_xs_dbentry **dataBase) |
86 { | 208 { |
87 FILE *inFile; | 209 FILE *inFile; |
88 char inLine[256]; | 210 gchar inLine[XMMS_SID_BUFSIZE]; |
89 int lineNum, linePos, i, j, k; | 211 gint lineNum, linePos, iOK; |
90 t_xs_hash tmpHash; | 212 t_xs_dbentry *tmpNode; |
91 | 213 |
92 | |
93 /* Try to open the file */ | 214 /* Try to open the file */ |
94 if ((inFile = fopen(pcFilename, "r")) == NULL) | 215 if ((inFile = fopen(dbFilename, "ra")) == NULL) |
95 { | 216 { |
96 fprintf(stderr, "hv!\n"); | 217 XSERR("Could not open SongLengthDB '%s'\n", dbFilename); |
97 return -1; | 218 return -1; |
98 } | 219 } |
99 | 220 |
100 | |
101 /* Read and parse the data */ | 221 /* Read and parse the data */ |
102 lineNum = 0; | 222 lineNum = 0; |
103 | 223 |
104 while (!feof(inFile)) | 224 while (!feof(inFile)) |
105 { | 225 { |
106 fgets(inLine, sizeof(inLine), inFile); | 226 fgets(inLine, sizeof(inLine), inFile); |
227 lineNum++; | |
228 | |
229 /* Check if it is datafield */ | |
230 if (isxdigit(inLine[0])) | |
231 { | |
232 /* Check the length of the hash */ | |
107 linePos = 0; | 233 linePos = 0; |
108 | 234 while (isxdigit(inLine[linePos])) linePos++; |
109 if (strlen(inLine) > 1) | 235 |
110 { | 236 if (linePos != XS_MD5HASH_LENGTH_CH) |
111 /* Find first character */ | 237 { |
112 xs_findnext(inLine, &linePos); | 238 XSERR("Invalid hash in SongLengthDB file '%s' line #%d!\n", |
113 | 239 dbFilename, lineNum); |
114 /* Check if it is a hash-line */ | 240 } else { |
115 if (isxdigit(inLine[linePos])) | 241 /* Allocate new node */ |
116 { | 242 if ((tmpNode = xs_db_node_new()) == NULL) |
117 i = linePos; | |
118 while (isxdigit(inLine[linePos])) linePos++; | |
119 | |
120 if ((linePos - i) != XS_HASH_LENGTH_CH) | |
121 { | 243 { |
122 XSERR("Invalid hash/syntax error in SongLengthDB file '%s' line #%d!\n", | 244 XSERR("Error allocating new node. Fatal error.\n"); |
123 pcFilename, lineNum); | 245 exit(5); |
246 } | |
247 | |
248 /* Get hash value */ | |
249 #if (XS_MD5HASH_LENGTH != 16) | |
250 #error Mismatch in hashcode length. Fix here. | |
251 #endif | |
252 sscanf(&inLine[0], "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", | |
253 (guint *) &(tmpNode->md5Hash[0]), (guint *) &(tmpNode->md5Hash[1]), | |
254 (guint *) &(tmpNode->md5Hash[2]), (guint *) &(tmpNode->md5Hash[3]), | |
255 (guint *) &(tmpNode->md5Hash[4]), (guint *) &(tmpNode->md5Hash[5]), | |
256 (guint *) &(tmpNode->md5Hash[6]), (guint *) &(tmpNode->md5Hash[7]), | |
257 (guint *) &(tmpNode->md5Hash[8]), (guint *) &(tmpNode->md5Hash[9]), | |
258 (guint *) &(tmpNode->md5Hash[10]), (guint *) &(tmpNode->md5Hash[11]), | |
259 (guint *) &(tmpNode->md5Hash[12]), (guint *) &(tmpNode->md5Hash[13]), | |
260 (guint *) &(tmpNode->md5Hash[14]), (guint *) &(tmpNode->md5Hash[15])); | |
261 | |
262 /* Get playtimes */ | |
263 if (inLine[linePos] != '=') | |
264 { | |
265 XSERR("'=' expected in SongLengthDB file '%s' line #%d, column #%d\n", | |
266 dbFilename, lineNum, linePos); | |
267 | |
268 xs_db_node_free(tmpNode); | |
124 } else { | 269 } else { |
125 /* Get hashcode value */ | 270 /* First playtime is after '=' */ |
126 for (j = 0; j < XS_HASH_LENGTH; j++) | 271 linePos++; |
272 iOK = 1; | |
273 | |
274 while ((linePos < strlen(inLine)) && (iOK)) | |
127 { | 275 { |
128 | 276 xs_findnext(inLine, &linePos); |
277 | |
278 if (tmpNode->nLengths < XS_STIL_MAXENTRY) | |
279 { | |
280 tmpNode->sLengths[tmpNode->nLengths] = | |
281 xs_gettime(inLine, &linePos); | |
282 tmpNode->nLengths++; | |
283 } else | |
284 iOK = 0; | |
129 } | 285 } |
130 | 286 |
131 /* Get playtimes */ | 287 /* Add an entry to db in memory */ |
132 xs_findnext(line, &linePos); | 288 if (iOK) |
133 | 289 xs_db_node_insert(tmpNode); |
134 if (line[linePos] != '=') | 290 else |
291 xs_db_node_free(tmpNode); | |
292 } | |
293 } | |
294 } else | |
295 if ((inLine[0] != ';') && (inLine[0] != '[')) | |
296 { | |
297 XSERR("Invalid line in SongLengthDB file '%s' line #%d\n", | |
298 dbFilename, lineNum); | |
299 } | |
300 | |
301 } /* while */ | |
302 | |
303 /* Close the file */ | |
304 fclose(inFile); | |
305 | |
306 return 0; | |
307 } | |
308 | |
309 | |
310 /* | |
311 * Compare two nodes' hashes | |
312 */ | |
313 gint xs_db_cmp(const void *pNode1, const void *pNode2) | |
314 { | |
315 /* We assume here that we never ever get NULL-pointers or similar */ | |
316 return xs_db_cmphash((*(t_xs_dbentry **) pNode1)->md5Hash, | |
317 (*(t_xs_dbentry **) pNode2)->md5Hash); | |
318 } | |
319 | |
320 | |
321 /* | |
322 * Initialize the song-length system | |
323 */ | |
324 gint xs_songlen_init(void) | |
325 { | |
326 t_xs_dbentry *pCurr; | |
327 gint i; | |
328 | |
329 /* Read the database */ | |
330 if (xs_cfg.playDBPath == NULL) | |
331 return -10; | |
332 | |
333 fprintf(stderr, "reading '%s'\n", xs_cfg.playDBPath); | |
334 | |
335 if (xs_db_read(xs_cfg.playDBPath, &xs_database) < 0) | |
336 return -9; | |
337 | |
338 fprintf(stderr, "read_done, now size DB for index\n"); | |
339 | |
340 /* Get size of db */ | |
341 pCurr = xs_database; | |
342 xs_dbnodes = 0; | |
343 while (pCurr) | |
344 { | |
345 xs_dbnodes++; | |
346 pCurr = pCurr->pNext; | |
347 } | |
348 | |
349 /* Check number of nodes */ | |
350 if (xs_dbnodes > 0) | |
351 { | |
352 fprintf(stderr, "allocating %i nodes...\n", xs_dbnodes); | |
353 /* Allocate memory for index-table */ | |
354 xs_dbindex = (t_xs_dbentry **) malloc(sizeof(t_xs_dbentry *) * xs_dbnodes); | |
355 if (xs_dbindex == NULL) return -6; | |
356 | |
357 /* Get node-pointers to table */ | |
358 i = 0; | |
359 pCurr = xs_database; | |
360 while (pCurr) | |
361 { | |
362 xs_dbindex[i++] = pCurr; | |
363 pCurr = pCurr->pNext; | |
364 } | |
365 | |
366 fprintf(stderr, "sorting!\n"); | |
367 /* Sort the indexes */ | |
368 qsort(xs_dbindex, xs_dbnodes, sizeof(t_xs_dbentry *), xs_db_cmp); | |
369 } | |
370 | |
371 /* OK */ | |
372 return 0; | |
373 } | |
374 | |
375 | |
376 /* | |
377 * Close song-length system | |
378 */ | |
379 gint xs_songlen_close(void) | |
380 { | |
381 t_xs_dbentry *pCurr, *pNext; | |
382 | |
383 /* Free the memory allocated for database */ | |
384 pCurr = xs_database; | |
385 while (pCurr) | |
386 { | |
387 pNext = pCurr->pNext; | |
388 xs_db_node_free(pCurr); | |
389 pCurr = pNext; | |
390 } | |
391 | |
392 /* Free memory allocated for indexes */ | |
393 if (xs_dbindex) | |
394 free(xs_dbindex); | |
395 | |
396 return 0; | |
397 } | |
398 | |
399 | |
400 /* | |
401 * Compute md5hash of given SID-file | |
402 */ | |
403 typedef struct { | |
404 guint8 magicID[4]; /* "PSID" magic identifier */ | |
405 guint16 version, /* Version number */ | |
406 dataOffset, /* Start of actual c64 data in file */ | |
407 loadAddress, /* Loading address */ | |
408 initAddress, /* Initialization address */ | |
409 playAddress, /* Play one frame */ | |
410 nSongs, /* Number of subsongs */ | |
411 startSong; /* Default starting song */ | |
412 guint32 speed; /* Speed */ | |
413 gchar sidName[32]; /* Descriptive text-fields, ASCIIZ */ | |
414 gchar sidAuthor[32]; | |
415 gchar sidCopyright[32]; | |
416 } t_xs_psidv1_header; | |
417 | |
418 | |
419 typedef struct { | |
420 guint16 flags; /* Flags */ | |
421 guint8 startPage, | |
422 pageLength; | |
423 guint16 reserved; | |
424 } t_xs_psidv2_header; | |
425 | |
426 | |
427 guint16 rd_be16(FILE *f) | |
428 { | |
429 return (((guint16) fgetc(f)) * 256) + | |
430 ((guint16) fgetc(f)); | |
431 } | |
432 | |
433 | |
434 guint32 rd_be32(FILE *f) | |
435 { | |
436 return (((guint32) fgetc(f)) * 16777216) + | |
437 (((guint32) fgetc(f)) * 65536) + | |
438 (((guint32) fgetc(f)) * 256) + | |
439 ((guint32) fgetc(f)); | |
440 } | |
441 | |
442 | |
443 gint rd_str(FILE *f, gchar *s, gint l) | |
444 { | |
445 return fread(s, sizeof(gchar), l, f); | |
446 } | |
447 | |
448 | |
449 gint xs_get_sid_hash(gchar *fileName, t_xs_md5hash hash) | |
450 { | |
451 FILE *inFile; | |
452 t_xs_md5state inState; | |
453 t_xs_psidv1_header psidH; | |
454 t_xs_psidv2_header psidH2; | |
455 guint8 *songData, ib8[2], i8; | |
456 gint iIndex, iRes, songDataLen; | |
457 | |
458 /* Try to open the file */ | |
459 if ((inFile = fopen(fileName, "rb")) == NULL) | |
460 return -1; | |
461 | |
462 /* Read PSID header in */ | |
463 rd_str(inFile, psidH.magicID, sizeof(psidH.magicID)); | |
464 if ((psidH.magicID[0] != 'P') || (psidH.magicID[1] != 'S') || | |
465 (psidH.magicID[2] != 'I') || (psidH.magicID[3] != 'D')) | |
466 return -2; | |
467 | |
468 psidH.version = rd_be16(inFile); | |
469 psidH.dataOffset = rd_be16(inFile); | |
470 psidH.loadAddress = rd_be16(inFile); | |
471 psidH.initAddress = rd_be16(inFile); | |
472 psidH.playAddress = rd_be16(inFile); | |
473 psidH.nSongs = rd_be16(inFile); | |
474 psidH.startSong = rd_be16(inFile); | |
475 psidH.speed = rd_be32(inFile); | |
476 | |
477 rd_str(inFile, psidH.sidName, sizeof(psidH.sidName)); | |
478 rd_str(inFile, psidH.sidAuthor, sizeof(psidH.sidAuthor)); | |
479 rd_str(inFile, psidH.sidCopyright, sizeof(psidH.sidCopyright)); | |
480 | |
481 /* Check if we need to load PSIDv2NG header ... */ | |
482 if (psidH.version == 2) | |
483 { | |
484 /* Yes, we need to */ | |
485 psidH2.flags = rd_be16(inFile); | |
486 psidH2.startPage = fgetc(inFile); | |
487 psidH2.pageLength = fgetc(inFile); | |
488 psidH2.reserved = rd_be16(inFile); | |
489 } | |
490 | |
491 /* Get data length and seek to data offset */ | |
492 fseek(inFile, 0L, SEEK_END); | |
493 songDataLen = ftell(inFile) - psidH.dataOffset; | |
494 fseek(inFile, psidH.dataOffset, SEEK_SET); | |
495 | |
496 /* Allocate memory */ | |
497 songData = (guint8 *) malloc(sizeof(guint8) * songDataLen); | |
498 if (songData == NULL) | |
499 { | |
500 fclose(inFile); | |
501 return -7; | |
502 } | |
503 | |
504 /* Read data to buffer */ | |
505 iRes = fread(songData, sizeof(guint8), songDataLen, inFile); | |
506 fclose(inFile); | |
507 | |
508 if (iRes != songDataLen) return -9; | |
509 | |
510 /* Initialize and start MD5-hash calculation */ | |
511 xs_md5_init(&inState); | |
512 if (psidH.loadAddress == 0) | |
513 /* COULD SOMEONE EXPLAIN WHY DO WE NEED THIS +2 STRIP???? */ | |
514 xs_md5_append(&inState, songData+2, iRes-2); | |
515 else | |
516 xs_md5_append(&inState, songData, iRes); | |
517 | |
518 free(songData); | |
519 | |
520 /* Append header data to hash */ | |
521 #define XSADDHASH(QDATAB) { ib8[0] = (QDATAB & 0xff); ib8[1] = (QDATAB >> 8); xs_md5_append(&inState, (guint8 *) &ib8, sizeof(ib8)); } | |
522 | |
523 XSADDHASH(psidH.initAddress) | |
524 XSADDHASH(psidH.playAddress) | |
525 XSADDHASH(psidH.nSongs) | |
526 | |
527 #undef XSADDHASH | |
528 | |
529 /* Append song speed data to hash */ | |
530 i8 = 0; | |
531 for (iIndex = 0; (iIndex < psidH.nSongs) && (iIndex < 32); iIndex++) | |
532 { | |
533 i8 = (psidH.speed & (1 << iIndex)) ? 60 : 0; | |
534 xs_md5_append(&inState, &i8, sizeof(i8)); | |
535 } | |
536 | |
537 /* Rest of songs (more than 32) */ | |
538 for (iIndex = 32; iIndex < psidH.nSongs; iIndex++) | |
539 { | |
540 xs_md5_append(&inState, &i8, sizeof(i8)); | |
541 } | |
542 | |
543 | |
544 /* PSIDv2NG specific */ | |
545 if (psidH.version == 2) | |
546 { | |
547 /* SEE SIDPLAY HEADERS FOR INFO */ | |
548 i8 = (psidH2.flags >> 2) & 3; | |
549 if (i8 == 2) | |
550 xs_md5_append(&inState, &i8, sizeof(i8)); | |
551 } | |
552 | |
553 /* Calculate the hash */ | |
554 xs_md5_finish(&inState, hash); | |
555 | |
556 return 0; | |
557 } | |
558 | |
559 | |
560 /* | |
561 * Get song length | |
562 */ | |
563 gint32 xs_get_songlength(gchar *fileName, gint subTune) | |
564 { | |
565 t_xs_dbentry *dbEntry; | |
566 t_xs_md5hash dbHash; | |
567 gint32 iResult; | |
568 | |
569 iResult = -1; | |
570 | |
571 switch (xs_cfg.playMethod) { | |
572 | |
573 case XMMS_SID_PMETHOD_DATABASE: | |
574 /* Get the hash and then look up from db */ | |
575 if (xs_get_sid_hash(fileName, dbHash) == 0) | |
576 { | |
577 fprinth(stderr, dbHash); | |
578 fprintf(stderr, "\n"); | |
579 dbEntry = xs_db_get(dbHash); | |
580 | |
581 if (dbEntry) | |
135 { | 582 { |
136 XSERR("Warning: '=' expected in line #%d in SongLengthDB file '%s'\n", | 583 if ((subTune >= 0) && (subTune < dbEntry->nLengths)) |
137 lineNum, pcFilename); | 584 iResult = dbEntry->sLengths[subTune]; |
138 } else { | 585 } |
139 linePos++; | |
140 | |
141 while (linePos < strlen(inLine)) | |
142 { | |
143 xs_findnext(line, &linePos); | |
144 printf("[%lis]", xs_gettime(inLine, &linePos)); | |
145 } | |
146 | |
147 | |
148 /* Add an entry to db in memory */ | |
149 } | |
150 } | |
151 } | |
152 else | |
153 if ((line[linePos] != ';') && (line[linePos] != '[')) | |
154 { | |
155 XSERR("Invalid line #%d in SongLengthDB file '%s'\n", lineNum, pcFilename); | |
156 } | |
157 | |
158 } /* strlen(line) > 1 */ | |
159 | |
160 lineNum++; | |
161 } | |
162 | |
163 fclose(inFile); | |
164 | |
165 return 0; | |
166 } | |
167 | |
168 | |
169 /* | |
170 * | |
171 */ | |
172 gint xs_db_delete(void) | |
173 { | |
174 /* Free the memory allocated for database */ | |
175 | |
176 return 0; | |
177 } | |
178 | |
179 | |
180 /* | |
181 * | |
182 */ | |
183 int xs_comparehashes(t_xs_hash *testHash1, t_xs_hash *testHash2) | |
184 { | |
185 int iIndex, iOK; | |
186 | |
187 iOK = 1; | |
188 iIndex = 0; | |
189 while ((iIndex < 16) && (iOK)) | |
190 { | |
191 if (testHash1[iIndex] != testHash2[iIndex]) | |
192 iOK = 0; | |
193 else | |
194 iIndex++; | |
195 } | |
196 | |
197 return iOK; | |
198 } | |
199 | |
200 | |
201 | |
202 | |
203 /* | |
204 * Get song length from database | |
205 */ | |
206 t_xs_dbentry * xs_db_get(gchar *pcFilename) | |
207 { | |
208 | |
209 return NULL; | |
210 } | |
211 | |
212 | |
213 gint32 xs_get_length(gchar *pcFilename, gint iSubTune) | |
214 { | |
215 gint32 iResult; | |
216 t_xs_dbentry *dbEntry; | |
217 t_xs_hash dbHash; | |
218 | |
219 iResult = -1; | |
220 | |
221 switch (xs_cfg.playMethod) { | |
222 | |
223 case XMMS_SID_PMETHOD_DATABASE: | |
224 | |
225 iResult = xs_db_get(pcFilename, &dbHash); | |
226 if (iResult >= 0) | |
227 { | |
228 } | |
229 | |
230 if (dbEntry) | |
231 { | |
232 if ((iSubTune >= 0) && (iSubTune < dbEntry->nlengths)) | |
233 iResult = dbEntry->lengths[iSubTune]; | |
234 else | |
235 iResult = -1; | |
236 } | 586 } |
237 break; | 587 break; |
238 | 588 |
239 case XMMS_SID_PMETHOD_MAXSILENCE: | 589 case XMMS_SID_PMETHOD_MAXSILENCE: |
240 case XMMS_SID_PMETHOD_NONE: | 590 case XMMS_SID_PMETHOD_NONE: |
253 iResult = xs_cfg.playMaxTime; | 603 iResult = xs_cfg.playMaxTime; |
254 else | 604 else |
255 iResult = -1; | 605 iResult = -1; |
256 } | 606 } |
257 | 607 |
258 XSDEBUG("fname='%s', sub=%i, res=%li\n", pcFilename, iSubTune, iResult); | 608 XSDEBUG("fname='%s', sub=%i, res=%i\n", fileName, subTune, iResult); |
259 | 609 |
260 return iResult; | 610 return iResult; |
261 } | 611 } |
262 | 612 |
613 |