Mercurial > hg > sidinfo
comparison sidlib.c @ 222:3a01518fffe0
Rename sidlib functions from si_* prefix to sidlib_*.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 27 Dec 2019 11:12:42 +0200 |
parents | 8db9830e5d97 |
children | a76276ff7ba8 |
comparison
equal
deleted
inserted
replaced
221:8db9830e5d97 | 222:3a01518fffe0 |
---|---|
24 // } * nnodes; | 24 // } * nnodes; |
25 th_md5hash_t hash; | 25 th_md5hash_t hash; |
26 } PSIDLibHdr; | 26 } PSIDLibHdr; |
27 | 27 |
28 | 28 |
29 BOOL si_fread_str(th_ioctx *ctx, char **str, const size_t len) | 29 BOOL sidlib_fread_str(th_ioctx *ctx, char **str, const size_t len) |
30 { | 30 { |
31 char *tmp = th_malloc(len + 1); | 31 char *tmp = th_malloc(len + 1); |
32 if (tmp == NULL) | 32 if (tmp == NULL) |
33 goto err; | 33 goto err; |
34 | 34 |
45 th_free(tmp); | 45 th_free(tmp); |
46 return FALSE; | 46 return FALSE; |
47 } | 47 } |
48 | 48 |
49 | 49 |
50 static BOOL si_read_hash_data(th_ioctx *ctx, PSIDHeader *psid, | 50 static BOOL sidlib_read_hash_data(th_ioctx *ctx, PSIDHeader *psid, |
51 th_md5state_t *state, const BOOL newSLDB) | 51 th_md5state_t *state, const BOOL newSLDB) |
52 { | 52 { |
53 uint8_t *data = NULL; | 53 uint8_t *data = NULL; |
54 BOOL ret = FALSE, first = TRUE; | 54 BOOL ret = FALSE, first = TRUE; |
55 size_t read; | 55 size_t read; |
103 th_free(data); | 103 th_free(data); |
104 return ret; | 104 return ret; |
105 } | 105 } |
106 | 106 |
107 | 107 |
108 BOOL si_read_sid_file(th_ioctx *ctx, PSIDHeader **ppsid, const BOOL newSLDB) | 108 BOOL sidlib_read_sid_file(th_ioctx *ctx, PSIDHeader **ppsid, const BOOL newSLDB) |
109 { | 109 { |
110 PSIDHeader *psid = NULL; | 110 PSIDHeader *psid = NULL; |
111 th_md5state_t state; | 111 th_md5state_t state; |
112 BOOL ret = FALSE; | 112 BOOL ret = FALSE; |
113 off_t hdrStart, hdrEnd; | 113 off_t hdrStart, hdrEnd; |
150 goto error; | 150 goto error; |
151 } | 151 } |
152 | 152 |
153 psid->isRSID = psid->magic[0] == 'R'; | 153 psid->isRSID = psid->magic[0] == 'R'; |
154 | 154 |
155 if (!si_fread_str(ctx, &psid->sidName, PSID_STR_LEN) || | 155 if (!sidlib_fread_str(ctx, &psid->sidName, PSID_STR_LEN) || |
156 !si_fread_str(ctx, &psid->sidAuthor, PSID_STR_LEN) || | 156 !sidlib_fread_str(ctx, &psid->sidAuthor, PSID_STR_LEN) || |
157 !si_fread_str(ctx, &psid->sidCopyright, PSID_STR_LEN)) | 157 !sidlib_fread_str(ctx, &psid->sidCopyright, PSID_STR_LEN)) |
158 { | 158 { |
159 th_io_error(ctx, ctx->status, | 159 th_io_error(ctx, ctx->status, |
160 "Error reading SID file header from '%s': %s.\n", | 160 "Error reading SID file header from '%s': %s.\n", |
161 ctx->filename, th_error_str(ctx->status)); | 161 ctx->filename, th_error_str(ctx->status)); |
162 goto error; | 162 goto error; |
188 { | 188 { |
189 // New Songlengths.md5 style hash calculation: | 189 // New Songlengths.md5 style hash calculation: |
190 // We just hash the whole file, so seek back to beginning .. | 190 // We just hash the whole file, so seek back to beginning .. |
191 thfseek(ctx, hdrStart, SEEK_SET); | 191 thfseek(ctx, hdrStart, SEEK_SET); |
192 | 192 |
193 if (!si_read_hash_data(ctx, psid, &state, FALSE)) | 193 if (!sidlib_read_hash_data(ctx, psid, &state, FALSE)) |
194 goto error; | 194 goto error; |
195 | 195 |
196 psid->dataSize -= hdrEnd - hdrStart; | 196 psid->dataSize -= hdrEnd - hdrStart; |
197 } | 197 } |
198 else | 198 else |
199 { | 199 { |
200 // "Old" Songlengths.txt style MD5 hash calculation | 200 // "Old" Songlengths.txt style MD5 hash calculation |
201 // We need to separately hash data etc. | 201 // We need to separately hash data etc. |
202 if (!si_read_hash_data(ctx, psid, &state, TRUE)) | 202 if (!sidlib_read_hash_data(ctx, psid, &state, TRUE)) |
203 goto error; | 203 goto error; |
204 | 204 |
205 // Append header data to hash | 205 // Append header data to hash |
206 th_md5_append_le16(&state, psid->initAddress); | 206 th_md5_append_le16(&state, psid->initAddress); |
207 th_md5_append_le16(&state, psid->playAddress); | 207 th_md5_append_le16(&state, psid->playAddress); |
241 // Free buffer | 241 // Free buffer |
242 return ret; | 242 return ret; |
243 } | 243 } |
244 | 244 |
245 | 245 |
246 void si_free_sid_file(PSIDHeader *psid) | 246 void sidlib_free_sid_file(PSIDHeader *psid) |
247 { | 247 { |
248 if (psid != NULL) | 248 if (psid != NULL) |
249 { | 249 { |
250 th_free(psid->sidName); | 250 th_free(psid->sidName); |
251 th_free(psid->sidAuthor); | 251 th_free(psid->sidAuthor); |
252 th_free(psid->sidCopyright); | 252 th_free(psid->sidCopyright); |
253 } | 253 } |
254 } | 254 } |
255 | 255 |
256 | 256 |
257 const char *si_get_sid_clock_str(const int flags) | 257 const char *sidlib_get_sid_clock_str(const int flags) |
258 { | 258 { |
259 switch (flags) | 259 switch (flags) |
260 { | 260 { |
261 case PSF_CLOCK_UNKNOWN : return "Unknown"; | 261 case PSF_CLOCK_UNKNOWN : return "Unknown"; |
262 case PSF_CLOCK_PAL : return "PAL 50Hz"; | 262 case PSF_CLOCK_PAL : return "PAL 50Hz"; |
265 default : return "?"; | 265 default : return "?"; |
266 } | 266 } |
267 } | 267 } |
268 | 268 |
269 | 269 |
270 const char *si_get_sid_model_str(const int flags) | 270 const char *sidlib_get_sid_model_str(const int flags) |
271 { | 271 { |
272 switch (flags) | 272 switch (flags) |
273 { | 273 { |
274 case PSF_MODEL_UNKNOWN : return "Unknown"; | 274 case PSF_MODEL_UNKNOWN : return "Unknown"; |
275 case PSF_MODEL_MOS6581 : return "MOS6581"; | 275 case PSF_MODEL_MOS6581 : return "MOS6581"; |
280 } | 280 } |
281 | 281 |
282 | 282 |
283 // Free memory allocated for given SLDB node | 283 // Free memory allocated for given SLDB node |
284 // | 284 // |
285 static void si_sldb_node_free(SIDLibSLDBNode *node) | 285 static void sidlib_sldb_node_free(SIDLibSLDBNode *node) |
286 { | 286 { |
287 if (node != NULL) | 287 if (node != NULL) |
288 { | 288 { |
289 th_free_r(&node->lengths); | 289 th_free_r(&node->lengths); |
290 th_free_r(&node); | 290 th_free_r(&node); |
292 } | 292 } |
293 | 293 |
294 | 294 |
295 // Insert given node to db linked list | 295 // Insert given node to db linked list |
296 // | 296 // |
297 static void si_sldb_node_insert(SIDLibSLDB *dbh, SIDLibSLDBNode *node) | 297 static void sidlib_sldb_node_insert(SIDLibSLDB *dbh, SIDLibSLDBNode *node) |
298 { | 298 { |
299 if (dbh->nodes != NULL) | 299 if (dbh->nodes != NULL) |
300 { | 300 { |
301 node->prev = dbh->nodes->prev; | 301 node->prev = dbh->nodes->prev; |
302 dbh->nodes->prev->next = node; | 302 dbh->nodes->prev->next = node; |
311 } | 311 } |
312 | 312 |
313 | 313 |
314 // Parse a time-entry in SLDB format | 314 // Parse a time-entry in SLDB format |
315 // | 315 // |
316 static int si_sldb_get_value(const char *str, size_t *pos) | 316 static int sidlib_sldb_get_value(const char *str, size_t *pos) |
317 { | 317 { |
318 int result = 0; | 318 int result = 0; |
319 | 319 |
320 while (isdigit(str[*pos])) | 320 while (isdigit(str[*pos])) |
321 result = (result * 10) + (str[(*pos)++] - '0'); | 321 result = (result * 10) + (str[(*pos)++] - '0'); |
322 | 322 |
323 return result; | 323 return result; |
324 } | 324 } |
325 | 325 |
326 | 326 |
327 static int si_sldb_gettime(const char *str, size_t *pos) | 327 static int sidlib_sldb_gettime(const char *str, size_t *pos) |
328 { | 328 { |
329 int result; | 329 int result; |
330 | 330 |
331 // Check if it starts with a digit | 331 // Check if it starts with a digit |
332 if (th_isdigit(str[*pos])) | 332 if (th_isdigit(str[*pos])) |
333 { | 333 { |
334 // Get minutes-field | 334 // Get minutes-field |
335 result = si_sldb_get_value(str, pos) * 60; | 335 result = sidlib_sldb_get_value(str, pos) * 60; |
336 | 336 |
337 // Check the field separator char | 337 // Check the field separator char |
338 if (str[*pos] == ':') | 338 if (str[*pos] == ':') |
339 { | 339 { |
340 // Get seconds-field | 340 // Get seconds-field |
341 (*pos)++; | 341 (*pos)++; |
342 result += si_sldb_get_value(str, pos); | 342 result += sidlib_sldb_get_value(str, pos); |
343 } | 343 } |
344 else | 344 else |
345 result = -2; | 345 result = -2; |
346 } | 346 } |
347 else | 347 else |
355 } | 355 } |
356 | 356 |
357 | 357 |
358 // Parse one SLDB definition line, return SLDB node | 358 // Parse one SLDB definition line, return SLDB node |
359 // | 359 // |
360 SIDLibSLDBNode *si_sldb_parse_entry(th_ioctx *ctx, const char *line) | 360 SIDLibSLDBNode *sidlib_sldb_parse_entry(th_ioctx *ctx, const char *line) |
361 { | 361 { |
362 SIDLibSLDBNode *node = NULL; | 362 SIDLibSLDBNode *node = NULL; |
363 size_t pos, tmpLen, savePos; | 363 size_t pos, tmpLen, savePos; |
364 BOOL isOK; | 364 BOOL isOK; |
365 int i; | 365 int i; |
398 isOK = TRUE; | 398 isOK = TRUE; |
399 while (pos < tmpLen && isOK) | 399 while (pos < tmpLen && isOK) |
400 { | 400 { |
401 th_findnext(line, &pos); | 401 th_findnext(line, &pos); |
402 | 402 |
403 if (si_sldb_gettime(line, &pos) >= 0) | 403 if (sidlib_sldb_gettime(line, &pos) >= 0) |
404 node->nlengths++; | 404 node->nlengths++; |
405 else | 405 else |
406 isOK = FALSE; | 406 isOK = FALSE; |
407 } | 407 } |
408 | 408 |
423 pos < tmpLen && i < node->nlengths && isOK; i++) | 423 pos < tmpLen && i < node->nlengths && isOK; i++) |
424 { | 424 { |
425 int l; | 425 int l; |
426 th_findnext(line, &pos); | 426 th_findnext(line, &pos); |
427 | 427 |
428 l = si_sldb_gettime(line, &pos); | 428 l = sidlib_sldb_gettime(line, &pos); |
429 if (l >= 0) | 429 if (l >= 0) |
430 node->lengths[i] = l; | 430 node->lengths[i] = l; |
431 else | 431 else |
432 isOK = FALSE; | 432 isOK = FALSE; |
433 } | 433 } |
434 | 434 |
435 return node; | 435 return node; |
436 | 436 |
437 error: | 437 error: |
438 si_sldb_node_free(node); | 438 sidlib_sldb_node_free(node); |
439 return NULL; | 439 return NULL; |
440 } | 440 } |
441 | 441 |
442 | 442 |
443 SIDLibSLDB * si_sldb_new(void) | 443 SIDLibSLDB * sidlib_sldb_new(void) |
444 { | 444 { |
445 return (SIDLibSLDB *) th_malloc0(sizeof(SIDLibSLDB)); | 445 return (SIDLibSLDB *) th_malloc0(sizeof(SIDLibSLDB)); |
446 } | 446 } |
447 | 447 |
448 | 448 |
449 // Read SLDB database to memory | 449 // Read SLDB database to memory |
450 // | 450 // |
451 int si_sldb_read(th_ioctx *ctx, SIDLibSLDB *dbh) | 451 int sidlib_sldb_read(th_ioctx *ctx, SIDLibSLDB *dbh) |
452 { | 452 { |
453 char *line = NULL; | 453 char *line = NULL; |
454 | 454 |
455 if ((line = th_malloc(PSID_BUFFER_SIZE)) == NULL) | 455 if ((line = th_malloc(PSID_BUFFER_SIZE)) == NULL) |
456 { | 456 { |
482 ctx->filename, ctx->line, line); | 482 ctx->filename, ctx->line, line); |
483 } | 483 } |
484 else | 484 else |
485 { | 485 { |
486 // Parse and add node to db | 486 // Parse and add node to db |
487 if ((tmnode = si_sldb_parse_entry(ctx, line)) != NULL) | 487 if ((tmnode = sidlib_sldb_parse_entry(ctx, line)) != NULL) |
488 { | 488 { |
489 si_sldb_node_insert(dbh, tmnode); | 489 sidlib_sldb_node_insert(dbh, tmnode); |
490 } | 490 } |
491 else | 491 else |
492 { | 492 { |
493 th_io_error(ctx, THERR_INVALID_DATA, | 493 th_io_error(ctx, THERR_INVALID_DATA, |
494 "Invalid entry in SongLengthDB file '%s' line #%d:\n%s\n", | 494 "Invalid entry in SongLengthDB file '%s' line #%d:\n%s\n", |
513 // Compare two given MD5-hashes. | 513 // Compare two given MD5-hashes. |
514 // Return: 0 if equal | 514 // Return: 0 if equal |
515 // negative if hash1 < hash2 | 515 // negative if hash1 < hash2 |
516 // positive if hash1 > hash2 | 516 // positive if hash1 > hash2 |
517 // | 517 // |
518 static int si_sldb_compare_hash(th_md5hash_t hash1, th_md5hash_t hash2) | 518 static int sidlib_sldb_compare_hash(th_md5hash_t hash1, th_md5hash_t hash2) |
519 { | 519 { |
520 int i, delta; | 520 int i, delta; |
521 | 521 |
522 for (i = delta = 0; i < TH_MD5HASH_LENGTH && !delta; i++) | 522 for (i = delta = 0; i < TH_MD5HASH_LENGTH && !delta; i++) |
523 delta = hash1[i] - hash2[i]; | 523 delta = hash1[i] - hash2[i]; |
526 } | 526 } |
527 | 527 |
528 | 528 |
529 // Compare two nodes. | 529 // Compare two nodes. |
530 // We assume here that we never ever get NULL-pointers. | 530 // We assume here that we never ever get NULL-pointers. |
531 static int si_sldb_compare_nodes(const void *node1, const void *node2) | 531 static int sidlib_sldb_compare_nodes(const void *node1, const void *node2) |
532 { | 532 { |
533 return si_sldb_compare_hash( | 533 return sidlib_sldb_compare_hash( |
534 (*(SIDLibSLDBNode **) node1)->hash, | 534 (*(SIDLibSLDBNode **) node1)->hash, |
535 (*(SIDLibSLDBNode **) node2)->hash); | 535 (*(SIDLibSLDBNode **) node2)->hash); |
536 } | 536 } |
537 | 537 |
538 | 538 |
539 // (Re)create index | 539 // (Re)create index |
540 // | 540 // |
541 int si_sldb_build_index(SIDLibSLDB * dbh) | 541 int sidlib_sldb_build_index(SIDLibSLDB * dbh) |
542 { | 542 { |
543 SIDLibSLDBNode *node; | 543 SIDLibSLDBNode *node; |
544 | 544 |
545 // Free old index | 545 // Free old index |
546 th_free_r(&dbh->pindex); | 546 th_free_r(&dbh->pindex); |
562 // Get node-pointers to table | 562 // Get node-pointers to table |
563 for (i = 0, node = dbh->nodes; node && i < dbh->nnodes; node = node->next) | 563 for (i = 0, node = dbh->nodes; node && i < dbh->nnodes; node = node->next) |
564 dbh->pindex[i++] = node; | 564 dbh->pindex[i++] = node; |
565 | 565 |
566 // Sort the indexes | 566 // Sort the indexes |
567 qsort(dbh->pindex, dbh->nnodes, sizeof(SIDLibSLDBNode *), si_sldb_compare_nodes); | 567 qsort(dbh->pindex, dbh->nnodes, sizeof(SIDLibSLDBNode *), sidlib_sldb_compare_nodes); |
568 } | 568 } |
569 | 569 |
570 return THERR_OK; | 570 return THERR_OK; |
571 } | 571 } |
572 | 572 |
573 | 573 |
574 // | 574 // |
575 // Read binary format SLDB | 575 // Read binary format SLDB |
576 // | 576 // |
577 int si_sldb_read_bin(th_ioctx *ctx, SIDLibSLDB *dbh) | 577 int sidlib_sldb_read_bin(th_ioctx *ctx, SIDLibSLDB *dbh) |
578 { | 578 { |
579 PSIDLibHdr hdr; | 579 PSIDLibHdr hdr; |
580 th_md5state_t state; | 580 th_md5state_t state; |
581 th_md5hash_t hash; | 581 th_md5hash_t hash; |
582 size_t n; | 582 size_t n; |
658 | 658 |
659 th_md5_append_ne16(&state, tmpl); | 659 th_md5_append_ne16(&state, tmpl); |
660 node->lengths[index] = tmpl; | 660 node->lengths[index] = tmpl; |
661 } | 661 } |
662 | 662 |
663 si_sldb_node_insert(dbh, node); | 663 sidlib_sldb_node_insert(dbh, node); |
664 dbh->pindex[n] = node; | 664 dbh->pindex[n] = node; |
665 } | 665 } |
666 | 666 |
667 // Read stored checksum hash | 667 // Read stored checksum hash |
668 if (!thfread_str(ctx, hdr.hash, sizeof(hdr.hash))) | 668 if (!thfread_str(ctx, hdr.hash, sizeof(hdr.hash))) |
675 | 675 |
676 return THERR_OK; | 676 return THERR_OK; |
677 } | 677 } |
678 | 678 |
679 | 679 |
680 int si_sldb_write_bin(th_ioctx *ctx, const SIDLibSLDB *dbh) | 680 int sidlib_sldb_write_bin(th_ioctx *ctx, const SIDLibSLDB *dbh) |
681 { | 681 { |
682 th_md5state_t state; | 682 th_md5state_t state; |
683 th_md5hash_t hash; | 683 th_md5hash_t hash; |
684 size_t n; | 684 size_t n; |
685 | 685 |
738 } | 738 } |
739 | 739 |
740 | 740 |
741 // Free a given song-length database | 741 // Free a given song-length database |
742 // | 742 // |
743 void si_sldb_free(SIDLibSLDB *dbh) | 743 void sidlib_sldb_free(SIDLibSLDB *dbh) |
744 { | 744 { |
745 if (dbh != NULL) | 745 if (dbh != NULL) |
746 { | 746 { |
747 SIDLibSLDBNode *node = dbh->nodes; | 747 SIDLibSLDBNode *node = dbh->nodes; |
748 while (node != NULL) | 748 while (node != NULL) |
749 { | 749 { |
750 SIDLibSLDBNode *next = node->next; | 750 SIDLibSLDBNode *next = node->next; |
751 si_sldb_node_free(node); | 751 sidlib_sldb_node_free(node); |
752 node = next; | 752 node = next; |
753 } | 753 } |
754 | 754 |
755 dbh->nodes = NULL; | 755 dbh->nodes = NULL; |
756 dbh->nnodes = 0; | 756 dbh->nnodes = 0; |
759 th_free(dbh); | 759 th_free(dbh); |
760 } | 760 } |
761 } | 761 } |
762 | 762 |
763 | 763 |
764 SIDLibSLDBNode *si_sldb_get_by_hash(SIDLibSLDB *dbh, th_md5hash_t hash) | 764 SIDLibSLDBNode *sidlib_sldb_get_by_hash(SIDLibSLDB *dbh, th_md5hash_t hash) |
765 { | 765 { |
766 SIDLibSLDBNode keyItem, *key, **item; | 766 SIDLibSLDBNode keyItem, *key, **item; |
767 | 767 |
768 memcpy(&keyItem.hash, hash, sizeof(th_md5hash_t)); | 768 memcpy(&keyItem.hash, hash, sizeof(th_md5hash_t)); |
769 key = &keyItem; | 769 key = &keyItem; |
770 item = bsearch(&key, dbh->pindex, dbh->nnodes, sizeof(dbh->pindex[0]), si_sldb_compare_nodes); | 770 item = bsearch(&key, dbh->pindex, dbh->nnodes, sizeof(dbh->pindex[0]), sidlib_sldb_compare_nodes); |
771 | 771 |
772 return (item != NULL) ? *item : NULL; | 772 return (item != NULL) ? *item : NULL; |
773 } | 773 } |