comparison src/xs_length.c @ 955:3c2efa18c422

Change semantics of xs_fread_be{32,16}() functions to match xs_fread_str() and xs_fread_byte() and change the PSID/RSID file parsing for SLDB MD5 calculation to use them. Also, fix the parser so that PSID/RSID v3 files are supported correctly.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 20 Nov 2012 21:28:39 +0200
parents ad97fd1524be
children 5e0a05c84694
comparison
equal deleted inserted replaced
954:a5b118c853f5 955:3c2efa18c422
368 } psidv2_header_t; 368 } psidv2_header_t;
369 369
370 370
371 static gint xs_get_sid_hash(const gchar *filename, xs_md5hash_t hash) 371 static gint xs_get_sid_hash(const gchar *filename, xs_md5hash_t hash)
372 { 372 {
373 XSFile *inFile; 373 XSFile *inFile = NULL;
374 xs_md5state_t inState; 374 xs_md5state_t inState;
375 psidv1_header_t psidH; 375 psidv1_header_t psidH;
376 psidv2_header_t psidH2; 376 psidv2_header_t psidH2;
377 guint8 *songData; 377 guint8 *songData = NULL;
378 guint8 ib8[2], i8; 378 guint8 ib8[2], i8;
379 gint index, result; 379 gint index, result;
380 380
381 /* Try to open the file */ 381 /* Try to open the file */
382 if ((inFile = xs_fopen(filename, "rb")) == NULL) 382 if ((inFile = xs_fopen(filename, "rb")) == NULL)
383 return -1; 383 goto error;
384 384
385 /* Read PSID header in */ 385 /* Read PSID header in */
386 xs_fread(psidH.magicID, sizeof(psidH.magicID), 1, inFile); 386 if (!xs_fread_str(inFile, psidH.magicID, sizeof(psidH.magicID)) ||
387 if (strncmp(psidH.magicID, "PSID", 4) && 387 !xs_fread_be16(inFile, &psidH.version) ||
388 strncmp(psidH.magicID, "RSID", 4)) 388 !xs_fread_be16(inFile, &psidH.dataOffset) ||
389 { 389 !xs_fread_be16(inFile, &psidH.loadAddress) ||
390 xs_fclose(inFile); 390 !xs_fread_be16(inFile, &psidH.initAddress) ||
391 xs_error("Not a PSID or RSID file '%s'\n", filename); 391 !xs_fread_be16(inFile, &psidH.playAddress) ||
392 return -2; 392 !xs_fread_be16(inFile, &psidH.nSongs) ||
393 } 393 !xs_fread_be16(inFile, &psidH.startSong) ||
394 394 !xs_fread_be32(inFile, &psidH.speed))
395 psidH.version = xs_fread_be16(inFile); 395 {
396 psidH.dataOffset = xs_fread_be16(inFile); 396 xs_error("Could not read PSID/RSID header from '%s'\n", filename);
397 psidH.loadAddress = xs_fread_be16(inFile); 397 goto error;
398 psidH.initAddress = xs_fread_be16(inFile); 398 }
399 psidH.playAddress = xs_fread_be16(inFile); 399
400 psidH.nSongs = xs_fread_be16(inFile); 400 if ((strncmp(psidH.magicID, "PSID", 4) &&
401 psidH.startSong = xs_fread_be16(inFile); 401 strncmp(psidH.magicID, "RSID", 4)) ||
402 psidH.speed = xs_fread_be32(inFile); 402 psidH.version < 1 || psidH.version > 3)
403 403 {
404 xs_fread(psidH.sidName, sizeof(gchar), sizeof(psidH.sidName), inFile); 404 xs_error("Not a supported PSID or RSID file '%s'\n", filename);
405 xs_fread(psidH.sidAuthor, sizeof(gchar), sizeof(psidH.sidAuthor), inFile); 405 goto error;
406 xs_fread(psidH.sidCopyright, sizeof(gchar), sizeof(psidH.sidCopyright), inFile); 406 }
407 407
408 if (xs_feof(inFile) || xs_ferror(inFile)) 408 if (!xs_fread_str(inFile, psidH.sidName, sizeof(psidH.sidName)) ||
409 { 409 !xs_fread_str(inFile, psidH.sidAuthor, sizeof(psidH.sidAuthor)) ||
410 xs_fclose(inFile); 410 !xs_fread_str(inFile, psidH.sidCopyright, sizeof(psidH.sidCopyright)))
411 {
411 xs_error("Error reading SID file header from '%s'\n", filename); 412 xs_error("Error reading SID file header from '%s'\n", filename);
412 return -4; 413 goto error;
413 } 414 }
414 415
415 /* Check if we need to load PSIDv2NG header ... */ 416 /* Check if we need to load PSIDv2NG header ... */
416 psidH2.flags = 0; /* Just silence a stupid gcc warning */ 417 psidH2.flags = 0; /* Just silence a stupid gcc warning */
417 418
418 if (psidH.version == 2) 419 if (psidH.version == 2 || psidH.version == 3)
419 { 420 {
420 /* Yes, we need to */ 421 /* Yes, we need to */
421 psidH2.flags = xs_fread_be16(inFile); 422 if (!xs_fread_be16(inFile, &psidH2.flags) ||
422 psidH2.startPage = xs_fgetc(inFile); 423 !xs_fread_byte(inFile, &psidH2.startPage) ||
423 psidH2.pageLength = xs_fgetc(inFile); 424 !xs_fread_byte(inFile, &psidH2.startPage) ||
424 psidH2.reserved = xs_fread_be16(inFile); 425 !xs_fread_be16(inFile, &psidH2.reserved))
426 {
427 xs_error("Error reading PSID/RSID v2+ extra header data from '%s'\n",
428 filename);
429 goto error;
430 }
425 } 431 }
426 432
427 /* Allocate buffer */ 433 /* Allocate buffer */
428 songData = (guint8 *) g_malloc(XS_SIDBUF_SIZE * sizeof(guint8)); 434 if ((songData = (guint8 *) g_malloc(XS_SIDBUF_SIZE)) == NULL)
429 if (!songData) 435 {
430 {
431 xs_fclose(inFile);
432 xs_error("Error allocating temp data buffer for file '%s'\n", filename); 436 xs_error("Error allocating temp data buffer for file '%s'\n", filename);
433 return -3; 437 goto error;
434 } 438 }
435 439
436 /* Read data to buffer */ 440 /* Read data to buffer */
437 result = xs_fread(songData, sizeof(guint8), XS_SIDBUF_SIZE, inFile); 441 result = xs_fread(songData, sizeof(guint8), XS_SIDBUF_SIZE, inFile);
438 xs_fclose(inFile); 442 xs_fclose(inFile);
477 /* Rest of songs (more than 32) */ 481 /* Rest of songs (more than 32) */
478 for (index = 32; index < psidH.nSongs; index++) 482 for (index = 32; index < psidH.nSongs; index++)
479 xs_md5_append(&inState, &i8, sizeof(i8)); 483 xs_md5_append(&inState, &i8, sizeof(i8));
480 484
481 /* PSIDv2NG specific */ 485 /* PSIDv2NG specific */
482 if (psidH.version == 2) 486 if (psidH.version == 2 || psidH.version == 3)
483 { 487 {
484 /* SEE SIDPLAY HEADERS FOR INFO */ 488 /* SEE SIDPLAY HEADERS FOR INFO */
485 i8 = (psidH2.flags >> 2) & 3; 489 i8 = (psidH2.flags >> 2) & 3;
486 if (i8 == 2) 490 if (i8 == 2)
487 xs_md5_append(&inState, &i8, sizeof(i8)); 491 xs_md5_append(&inState, &i8, sizeof(i8));
489 493
490 /* Calculate the hash */ 494 /* Calculate the hash */
491 xs_md5_finish(&inState, hash); 495 xs_md5_finish(&inState, hash);
492 496
493 return 0; 497 return 0;
498
499 error:
500 if (inFile != NULL)
501 xs_fclose(inFile);
502 g_free(songData);
503 return -1;
494 } 504 }
495 505
496 506
497 /* Get node from db index via binary search 507 /* Get node from db index via binary search
498 */ 508 */