From ab9460c3f4616eff2b462179cba78ec79387cc70 Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 10 Jul 2004 11:06:00 +0000 Subject: [PATCH] Hoist some more common image routines and make image drivers look more common. In particular we now have a "cue", "source", and "access-mode" parameters defined even when "cue" and "source" are the same as in NRG. The _img_private_t's for the image drivers are now more similar if not the same. Some memory leaks when there are error conditions in opening image drivers have been fixed. --- lib/image.h | 8 +- lib/image/bincue.c | 128 +++++---------------------- lib/image/cdrdao.c | 214 ++++++++++++--------------------------------- lib/image/nrg.c | 99 +++++++++------------ lib/image_common.h | 107 ++++++++++++++++++++++- 5 files changed, 226 insertions(+), 330 deletions(-) diff --git a/lib/image.h b/lib/image.h index 7a718f6b..6115a361 100644 --- a/lib/image.h +++ b/lib/image.h @@ -1,5 +1,5 @@ /* - $Id: image.h,v 1.1 2004/07/10 02:17:59 rocky Exp $ + $Id: image.h,v 1.2 2004/07/10 11:06:00 rocky Exp $ Copyright (C) 2004 Rocky Bernstein @@ -18,7 +18,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* Common image routines. */ +/*! + Header for image drivers. In contrast to image_common.h which contains + routines, this header like most C headers does not depend on anything + defined before it is included. +*/ #ifndef __CDIO_IMAGE_H__ #define __CDIO_IMAGE_H__ diff --git a/lib/image/bincue.c b/lib/image/bincue.c index b227cb8b..ad653371 100644 --- a/lib/image/bincue.c +++ b/lib/image/bincue.c @@ -1,5 +1,5 @@ /* - $Id: bincue.c,v 1.30 2004/07/10 02:17:59 rocky Exp $ + $Id: bincue.c,v 1.31 2004/07/10 11:06:00 rocky Exp $ Copyright (C) 2002, 2003, 2004 Rocky Bernstein Copyright (C) 2001 Herbert Valerio Riedel @@ -26,7 +26,7 @@ (*.cue). */ -static const char _rcsid[] = "$Id: bincue.c,v 1.30 2004/07/10 02:17:59 rocky Exp $"; +static const char _rcsid[] = "$Id: bincue.c,v 1.31 2004/07/10 11:06:00 rocky Exp $"; #include "image.h" #include "cdio_assert.h" @@ -77,13 +77,14 @@ typedef struct { internal_position_t pos; char *psz_cue_name; - char *psz_mcn; /* Media Catalog Number. */ + char *psz_mcn; /* Media Catalog Number (5.22.3) + exactly 13 bytes */ track_info_t tocent[CDIO_CD_MAX_TRACKS+1]; /* entry info for each track add 1 for leadout. */ track_t i_tracks; /* number of tracks in image */ track_t i_first_track; /* track number of first track */ cdtext_t *cdtext; /* CD-TEXT */ - bool have_cue; + track_format_t mode; } _img_private_t; #if 0 @@ -125,13 +126,11 @@ _bincue_init (_img_private_t *env) /* Read in CUE sheet. */ #if 0 - env->have_cue = _bincue_image_read_cue(env); + if ( !_bincue_image_read_cue(env) ) return false; #else - env->have_cue = parse_cuefile(env, env->psz_cue_name); + if ( !parse_cuefile(env, env->psz_cue_name) ) return false; #endif - if ( !env->have_cue ) return false; - /* Fake out leadout track and sector count for last track*/ cdio_lsn_to_msf (lead_lsn, &env->tocent[env->i_tracks].start_msf); env->tocent[env->i_tracks].start_lba = cdio_lsn_to_lba(lead_lsn); @@ -816,7 +815,6 @@ _bincue_image_read_cue (_img_private_t *env) } } } - env->have_cue = env->i_tracks != 0; fclose (fp); return true; @@ -967,95 +965,6 @@ _read_mode2_sectors_bincue (void *user_data, void *data, lsn_t lsn, return 0; } -#define free_if_notnull(obj) \ - if (NULL != obj) { free(obj); obj=NULL; }; - -static void -_free_bincue (void *user_data) -{ - _img_private_t *env = user_data; - track_t i_track; - - if (NULL == env) return; - - for (i_track=0; i_track < env->i_tracks; i_track++) { - free_if_notnull(env->tocent[i_track].filename); - free_if_notnull(env->tocent[i_track].isrc); - cdtext_delete(env->tocent[i_track].cdtext); - } - - free_if_notnull(env->psz_mcn); - free_if_notnull(env->psz_cue_name); - cdtext_delete(env->cdtext); - cdio_generic_stdio_free(env); - free(env); -} - -/*! - Eject media -- there's nothing to do here except free resources. - We always return 2. - */ -static int -_eject_media_bincue(void *user_data) -{ - _free_bincue (user_data); - return 2; -} - -/*! - Set the arg "key" with "value" in the source device. - Currently "source" to set the source device in I/O operations - is the only valid key. - - 0 is returned if no error was found, and nonzero if there as an error. -*/ -static int -_set_arg_bincue (void *user_data, const char key[], const char value[]) -{ - _img_private_t *env = user_data; - - if (!strcmp (key, "source")) - { - free_if_notnull (env->gen.source_name); - - if (!value) - return -2; - - env->gen.source_name = strdup (value); - } - else if (!strcmp (key, "cue")) - { - free_if_notnull (env->psz_cue_name); - - if (!value) - return -2; - - env->psz_cue_name = strdup (value); - } - else - return -1; - - return 0; -} - -/*! - Return the value associated with the key "arg". -*/ -static const char * -_get_arg_bincue (void *user_data, const char key[]) -{ - _img_private_t *env = user_data; - - if (!strcmp (key, "source")) { - return env->gen.source_name; - } else if (!strcmp (key, "cue")) { - return env->psz_cue_name; - } else if (!strcmp(key, "access-mode")) { - return "image"; - } - return NULL; -} - /*! Return an array of strings giving possible BIN/CUE disk images. */ @@ -1275,9 +1184,9 @@ cdio_open_cue (const char *psz_cue_name) char *psz_bin_name; cdio_funcs _funcs = { - .eject_media = _eject_media_bincue, - .free = _free_bincue, - .get_arg = _get_arg_bincue, + .eject_media = _eject_media_image, + .free = _free_image, + .get_arg = _get_arg_image, .get_devices = cdio_get_devices_bincue, .get_default_device = cdio_get_default_device_bincue, .get_drive_cap = _get_drive_cap_bincue, @@ -1295,19 +1204,22 @@ cdio_open_cue (const char *psz_cue_name) .read_mode1_sectors = _read_mode1_sectors_bincue, .read_mode2_sector = _read_mode2_sector_bincue, .read_mode2_sectors = _read_mode2_sectors_bincue, - .set_arg = _set_arg_bincue, + .set_arg = _set_arg_image, .stat_size = _stat_size_bincue }; if (NULL == psz_cue_name) return NULL; _data = _cdio_malloc (sizeof (_img_private_t)); - (_data)->gen.init = false; - (_data)->psz_cue_name = NULL; + _data->gen.init = false; + _data->psz_cue_name = NULL; ret = cdio_new (_data, &_funcs); - if (ret == NULL) return NULL; + if (ret == NULL) { + free(_data); + return NULL; + } psz_bin_name = cdio_is_cuefile(psz_cue_name); @@ -1316,14 +1228,14 @@ cdio_open_cue (const char *psz_cue_name) psz_cue_name); } - _set_arg_bincue (_data, "cue", psz_cue_name); - _set_arg_bincue (_data, "source", psz_bin_name); + _set_arg_image (_data, "cue", psz_cue_name); + _set_arg_image (_data, "source", psz_bin_name); free(psz_bin_name); if (_bincue_init(_data)) { return ret; } else { - _free_bincue(_data); + _free_image(_data); free(ret); return NULL; } diff --git a/lib/image/cdrdao.c b/lib/image/cdrdao.c index 82a9322b..ec8501a8 100644 --- a/lib/image/cdrdao.c +++ b/lib/image/cdrdao.c @@ -1,5 +1,5 @@ /* - $Id: cdrdao.c,v 1.16 2004/07/10 02:17:59 rocky Exp $ + $Id: cdrdao.c,v 1.17 2004/07/10 11:06:00 rocky Exp $ Copyright (C) 2004 Rocky Bernstein toc reading routine adapted from cuetools @@ -25,7 +25,7 @@ (*.cue). */ -static const char _rcsid[] = "$Id: cdrdao.c,v 1.16 2004/07/10 02:17:59 rocky Exp $"; +static const char _rcsid[] = "$Id: cdrdao.c,v 1.17 2004/07/10 11:06:00 rocky Exp $"; #include "image.h" #include "cdio_assert.h" @@ -76,17 +76,15 @@ typedef struct { generic_img_private_t gen; internal_position_t pos; - bool sector_2336; /* Playstation (PSX) uses 2336-byte sectors */ - - char *psz_toc_name; + char *psz_cue_name; char *psz_mcn; /* Media Catalog Number (5.22.3) exactly 13 bytes */ track_info_t tocent[CDIO_CD_MAX_TRACKS+1]; /* entry info for each track add 1 for leadout. */ track_t i_tracks; /* number of tracks in image */ track_t i_first_track; /* track number of first track */ + cdtext_t *cdtext; /* CD-TEXT */ track_format_t mode; - bool b_have_cdrdao; } _img_private_t; static uint32_t _stat_size_cdrdao (void *user_data); @@ -113,7 +111,7 @@ _init_cdrdao (_img_private_t *env) env->psz_mcn = NULL; /* Read in TOC sheet. */ - if ( !parse_tocfile(env, env->psz_toc_name) ) return false; + if ( !parse_tocfile(env, env->psz_cue_name) ) return false; lead_lsn = _stat_size_cdrdao( (_img_private_t *) env); @@ -238,15 +236,13 @@ _stat_size_cdrdao (void *user_data) { _img_private_t *env = user_data; long size; - int blocksize = env->sector_2336 - ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE_RAW; size = cdio_stream_stat (env->tocent[0].data_source); - if (size % blocksize) + if (size % CDIO_CD_FRAMESIZE_RAW) { cdio_warn ("image %s size (%ld) not multiple of blocksize (%d)", - env->tocent[0].filename, size, blocksize); + env->tocent[0].filename, size, CDIO_CD_FRAMESIZE_RAW); if (size % M2RAW_SECTOR_SIZE == 0) cdio_warn ("this may be a 2336-type disc image"); else if (size % CDIO_CD_FRAMESIZE_RAW == 0) @@ -254,7 +250,7 @@ _stat_size_cdrdao (void *user_data) /* exit (EXIT_FAILURE); */ } - size /= blocksize; + size /= CDIO_CD_FRAMESIZE_RAW; return size; } @@ -262,11 +258,11 @@ _stat_size_cdrdao (void *user_data) #define MAXLINE 512 #define UNIMPLIMENTED_MSG \ cdio_log(log_level, "%s line %d: unimplimented keyword: %s", \ - psz_toc_name, i_line, keyword) + psz_cue_name, i_line, keyword) static bool -parse_tocfile (_img_private_t *cd, const char *psz_toc_name) +parse_tocfile (_img_private_t *cd, const char *psz_cue_name) { char line[MAXLINE]; FILE *fp; @@ -275,13 +271,13 @@ parse_tocfile (_img_private_t *cd, const char *psz_toc_name) int i = -1; cdio_log_level_t log_level = (NULL == cd) ? CDIO_LOG_INFO : CDIO_LOG_WARN; - if (NULL == psz_toc_name) + if (NULL == psz_cue_name) return false; - fp = fopen (psz_toc_name, "r"); + fp = fopen (psz_cue_name, "r"); if (fp == NULL) { cdio_log(log_level, "error opening %s for reading: %s", - psz_toc_name, strerror(errno)); + psz_cue_name, strerror(errno)); return false; } @@ -303,7 +299,7 @@ parse_tocfile (_img_private_t *cd, const char *psz_toc_name) if (13 != strlen(psz_field)) { cdio_log(log_level, "%s line %d after word CATALOG:", - psz_toc_name, i_line); + psz_cue_name, i_line); cdio_log(log_level, "Token %s has length %ld. Should be 13 digits.", psz_field, (long int) strlen(psz_field)); @@ -316,7 +312,7 @@ parse_tocfile (_img_private_t *cd, const char *psz_toc_name) if (!isdigit(psz_field[i])) { cdio_log(log_level, "%s line %d after word CATALOG:", - psz_toc_name, i_line); + psz_cue_name, i_line); cdio_log(log_level, "Character \"%c\" at postition %i of token \"%s\"" " is not all digits.", @@ -329,7 +325,7 @@ parse_tocfile (_img_private_t *cd, const char *psz_toc_name) } else { cdio_log(log_level, "%s line %d after word CATALOG:", - psz_toc_name, i_line); + psz_cue_name, i_line); cdio_log(log_level, "Expecting 13 digits; nothing seen."); goto err_exit; } @@ -441,7 +437,7 @@ parse_tocfile (_img_private_t *cd, const char *psz_toc_name) } } else { cdio_log(log_level, "%s line %d after TRACK:", - psz_toc_name, i_line); + psz_cue_name, i_line); cdio_log(log_level, "'%s' not a valid mode.", psz_field); goto err_exit; } @@ -518,7 +514,7 @@ parse_tocfile (_img_private_t *cd, const char *psz_toc_name) /* Todo: do something about reusing existing files. */ if (!(cd->tocent[i].data_source = cdio_stdio_new (psz_field))) { cdio_warn ("%s line %d: can't open file `%s' for reading", - psz_toc_name, i_line, psz_field); + psz_cue_name, i_line, psz_field); goto err_exit; } } @@ -528,7 +524,7 @@ parse_tocfile (_img_private_t *cd, const char *psz_toc_name) lba_t lba = cdio_lsn_to_lba(cdio_mmssff_to_lba (psz_field)); if (CDIO_INVALID_LBA == lba) { cdio_log(log_level, "%s line %d: invalid MSF string %s", - psz_toc_name, i_line, psz_field); + psz_cue_name, i_line, psz_field); goto err_exit; } @@ -652,7 +648,7 @@ parse_tocfile (_img_private_t *cd, const char *psz_toc_name) /* unrecognized line */ } else { cdio_log(log_level, "%s line %d: warning: unrecognized keyword: %s", - psz_toc_name, i_line, keyword); + psz_cue_name, i_line, keyword); goto err_exit; } } @@ -668,12 +664,12 @@ parse_tocfile (_img_private_t *cd, const char *psz_toc_name) format_error: cdio_log(log_level, "%s line %d after keyword %s", - psz_toc_name, i_line, keyword); + psz_cue_name, i_line, keyword); goto err_exit; not_in_global_section: cdio_log(log_level, "%s line %d: keyword %s only allowed in global section", - psz_toc_name, i_line, keyword); + psz_cue_name, i_line, keyword); err_exit: fclose (fp); @@ -726,19 +722,14 @@ _read_mode1_sector_cdrdao (void *user_data, void *data, lsn_t lsn, _img_private_t *env = user_data; int ret; char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, }; - int blocksize = env->sector_2336 - ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE_RAW; - ret = cdio_stream_seek (env->tocent[0].data_source, lsn * blocksize, - SEEK_SET); + ret = cdio_stream_seek (env->tocent[0].data_source, + lsn * CDIO_CD_FRAMESIZE_RAW, SEEK_SET); if (ret!=0) return ret; /* FIXME: Not completely sure the below is correct. */ - ret = cdio_stream_read (env->tocent[0].data_source, - env->sector_2336 - ? (buf + CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE) - : buf, - blocksize, 1); + ret = cdio_stream_read (env->tocent[0].data_source, buf, + CDIO_CD_FRAMESIZE_RAW, 1); if (ret==0) return ret; memcpy (data, buf + CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE, @@ -788,18 +779,12 @@ _read_mode2_sector_cdrdao (void *user_data, void *data, lsn_t lsn, Review this sector 2336 stuff later. */ - int blocksize = env->sector_2336 - ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE_RAW; - - ret = cdio_stream_seek (env->tocent[0].data_source, lsn * blocksize, - SEEK_SET); + ret = cdio_stream_seek (env->tocent[0].data_source, + lsn * CDIO_CD_FRAMESIZE_RAW, SEEK_SET); if (ret!=0) return ret; - ret = cdio_stream_read (env->tocent[0].data_source, - env->sector_2336 - ? (buf + CDIO_CD_SYNC_SIZE + CDIO_CD_HEADER_SIZE) - : buf, - blocksize, 1); + ret = cdio_stream_read (env->tocent[0].data_source, buf, + CDIO_CD_FRAMESIZE_RAW, 1); if (ret==0) return ret; @@ -825,104 +810,16 @@ _read_mode2_sectors_cdrdao (void *user_data, void *data, lsn_t lsn, _img_private_t *env = user_data; int i; int retval; - unsigned int blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE; for (i = 0; i < nblocks; i++) { if ( (retval = _read_mode2_sector_cdrdao (env, - ((char *)data) + (blocksize * i), + ((char *)data) + (CDIO_CD_FRAMESIZE * i), lsn + i, b_form2)) ) return retval; } return 0; } -#define free_if_notnull(obj) \ - if (NULL != obj) { free(obj); obj=NULL; }; - -static void -_free_cdrdao (void *obj) -{ - _img_private_t *env = obj; - int i; - - if (NULL == env) return; - free_if_notnull(env->psz_mcn); - for (i=0; ii_tracks; i++) { - if (env->tocent[i].data_source) - cdio_stdio_destroy (env->tocent[i].data_source); - free_if_notnull(env->tocent[i].isrc); - free_if_notnull(env->tocent[i].filename); - } - free_if_notnull(env->psz_toc_name); - cdio_generic_stdio_free(env); - free(env); -} - -/*! - Eject media -- there's nothing to do here except free resources. - We always return 2. - */ -static int -_eject_media_cdrdao(void *obj) -{ - _free_cdrdao (obj); - return 2; -} - -/*! - Set the arg "key" with "value" in the source device. - Currently "source" to set the source device in I/O operations - is the only valid key. - - 0 is returned if no error was found, and nonzero if there as an error. -*/ -static int -_set_arg_cdrdao (void *user_data, const char key[], const char value[]) -{ - _img_private_t *env = user_data; - - if (!strcmp (key, "sector")) - { - if (!strcmp (value, "2336")) - env->sector_2336 = true; - else if (!strcmp (value, "2352")) - env->sector_2336 = false; - else - return -2; - } - else if (!strcmp (key, "toc")) - { - free_if_notnull (env->psz_toc_name); - - if (!value) - return -2; - - env->psz_toc_name = strdup (value); - } - else - return -1; - - return 0; -} - -/*! - Return the value associated with the key "arg". -*/ -static const char * -_get_arg_cdrdao (void *user_data, const char key[]) -{ - _img_private_t *env = user_data; - - if (!strcmp (key, "source")) { - return env->tocent[0].filename; - } else if (!strcmp (key, "toc")) { - return env->psz_toc_name; - } else if (!strcmp(key, "access-mode")) { - return "image"; - } - return NULL; -} - /*! Return an array of strings giving possible TOC disk images. */ @@ -1040,18 +937,18 @@ _get_lba_track_cdrdao(void *user_data, track_t i_track) */ bool -cdio_is_tocfile(const char *psz_toc_name) +cdio_is_tocfile(const char *psz_cue_name) { int i; - if (psz_toc_name == NULL) return false; + if (psz_cue_name == NULL) return false; - i=strlen(psz_toc_name)-strlen("toc"); + i=strlen(psz_cue_name)-strlen("toc"); if (i>0) { - if ( (psz_toc_name[i]=='t' && psz_toc_name[i+1]=='o' && psz_toc_name[i+2]=='c') - || (psz_toc_name[i]=='T' && psz_toc_name[i+1]=='O' && psz_toc_name[i+2]=='C') ) { - return parse_tocfile(NULL, psz_toc_name); + if ( (psz_cue_name[i]=='t' && psz_cue_name[i+1]=='o' && psz_cue_name[i+2]=='c') + || (psz_cue_name[i]=='T' && psz_cue_name[i+1]=='O' && psz_cue_name[i+2]=='C') ) { + return parse_tocfile(NULL, psz_cue_name); } } return false; @@ -1077,15 +974,15 @@ cdio_open_am_cdrdao (const char *psz_source_name, const char *psz_access_mode) ones to set that up. */ CdIo * -cdio_open_cdrdao (const char *psz_toc_name) +cdio_open_cdrdao (const char *psz_cue_name) { CdIo *ret; _img_private_t *_data; cdio_funcs _funcs = { - .eject_media = _eject_media_cdrdao, - .free = _free_cdrdao, - .get_arg = _get_arg_cdrdao, + .eject_media = _eject_media_image, + .free = _free_image, + .get_arg = _get_arg_image, .get_devices = cdio_get_devices_cdrdao, .get_default_device = cdio_get_default_device_cdrdao, .get_drive_cap = _get_drive_cap_cdrdao, @@ -1103,35 +1000,38 @@ cdio_open_cdrdao (const char *psz_toc_name) .read_mode1_sectors = _read_mode1_sectors_cdrdao, .read_mode2_sector = _read_mode2_sector_cdrdao, .read_mode2_sectors = _read_mode2_sectors_cdrdao, - .set_arg = _set_arg_cdrdao, + .set_arg = _set_arg_image, .stat_size = _stat_size_cdrdao }; - if (NULL == psz_toc_name) return NULL; + if (NULL == psz_cue_name) return NULL; - _data = _cdio_malloc (sizeof (_img_private_t)); - (_data)->gen.init = false; - (_data)->sector_2336 = false; - (_data)->psz_toc_name = NULL; - (_data)->gen.data_source = NULL; - (_data)->gen.source_name = NULL; + _data = _cdio_malloc (sizeof (_img_private_t)); + _data->gen.init = false; + _data->psz_cue_name = NULL; + _data->gen.data_source = NULL; + _data->gen.source_name = NULL; ret = cdio_new (_data, &_funcs); - if (ret == NULL) return NULL; + if (ret == NULL) { + free(_data); + return NULL; + } - if (!cdio_is_tocfile(psz_toc_name)) { + if (!cdio_is_tocfile(psz_cue_name)) { cdio_debug ("source name %s is not recognized as a TOC file", - psz_toc_name); + psz_cue_name); return NULL; } - _set_arg_cdrdao (_data, "toc", psz_toc_name); + _set_arg_image (_data, "cue", psz_cue_name); + _set_arg_image (_data, "source", psz_cue_name); if (_init_cdrdao(_data)) { return ret; } else { - _free_cdrdao(_data); + _free_image(_data); free(ret); return NULL; } diff --git a/lib/image/nrg.c b/lib/image/nrg.c index 45ed110d..1a7acae6 100644 --- a/lib/image/nrg.c +++ b/lib/image/nrg.c @@ -1,5 +1,5 @@ /* - $Id: nrg.c,v 1.27 2004/07/10 02:17:59 rocky Exp $ + $Id: nrg.c,v 1.28 2004/07/10 11:06:00 rocky Exp $ Copyright (C) 2003, 2004 Rocky Bernstein Copyright (C) 2001, 2003 Herbert Valerio Riedel @@ -45,7 +45,7 @@ #include "_cdio_stdio.h" #include "nrg.h" -static const char _rcsid[] = "$Id: nrg.c,v 1.27 2004/07/10 02:17:59 rocky Exp $"; +static const char _rcsid[] = "$Id: nrg.c,v 1.28 2004/07/10 11:06:00 rocky Exp $"; /* reader */ @@ -70,6 +70,20 @@ typedef struct { This must be first. */ generic_img_private_t gen; internal_position_t pos; + + /* This is common to all image drivers... */ + char *psz_cue_name; + char *psz_mcn; /* Media Catalog Number (5.22.3) */ + + track_info_t tocent[CDIO_CD_MAX_TRACKS+1]; /* entry info for each track + add 1 for leadout. */ + track_t i_tracks; /* number of tracks in image */ + track_t i_first_track; /* track number of first track */ + cdtext_t *cdtext; /* CD-TEXT */ + track_format_t mode; + + /* Nero Specific stuff. Note: for the image_free to work, this *must* + be last. */ bool is_dao; /* True if some of disk at once. False if some sort of track at once. */ uint32_t mtyp; /* Value of MTYP (media type?) tag */ @@ -78,16 +92,11 @@ typedef struct { /* This is a hack because I don't really understnad NERO better. */ bool is_cues; - char *psz_mcn; /* Media Catalog Number (5.22.3) */ - track_info_t tocent[CDIO_CD_MAX_TRACKS+1]; /* entry info for each track - add 1 for leadout. */ - track_t i_tracks; /* number of tracks in image */ - track_t i_first_track; /* track number of first track */ CdioList *mapping; /* List of track information */ uint32_t size; } _img_private_t; -static bool parse_nrg (_img_private_t *env, const char *psz_nrg_name); +static bool parse_nrg (_img_private_t *env, const char *psz_cue_name); static uint32_t _stat_size_nrg (void *user_data); #include "image_common.h" @@ -994,8 +1003,10 @@ _free_nrg (void *user_data) if (NULL == env) return; if (NULL != env->mapping) _cdio_list_free (env->mapping, true); - cdio_generic_stdio_free(env); - free(env); + + /* The remaining part of the image is like the other image drivers, + so free that in the same way. */ + _free_image(user_data); } /*! @@ -1009,45 +1020,6 @@ _eject_media_nrg(void *obj) return 2; } -/* - Set the device to use in I/O operations. -*/ -static int -_set_arg_nrg (void *user_data, const char key[], const char value[]) -{ - _img_private_t *env = user_data; - - if (!strcmp (key, "source")) - { - free (env->gen.source_name); - - if (!value) - return -2; - - env->gen.source_name = strdup (value); - } - else - return -1; - - return 0; -} - -/*! - Return the value associated with the key "arg". -*/ -static const char * -_get_arg_nrg (void *user_data, const char key[]) -{ - _img_private_t *env = user_data; - - if (!strcmp (key, "source")) { - return env->gen.source_name; - } else if (!strcmp(key, "access-mode")) { - return "image"; - } - return NULL; -} - /*! Return an array of strings giving possible NRG disk images. */ @@ -1198,7 +1170,7 @@ cdio_open_nrg (const char *psz_source) cdio_funcs _funcs = { .eject_media = _eject_media_nrg, .free = _free_nrg, - .get_arg = _get_arg_nrg, + .get_arg = _get_arg_image, .get_devices = cdio_get_devices_nrg, .get_default_device = cdio_get_default_device_nrg, .get_drive_cap = _get_drive_cap_nrg, @@ -1216,7 +1188,7 @@ cdio_open_nrg (const char *psz_source) .read_mode1_sectors = _read_mode1_sectors_nrg, .read_mode2_sector = _read_mode2_sector_nrg, .read_mode2_sectors = _read_mode2_sectors_nrg, - .set_arg = _set_arg_nrg, + .set_arg = _set_arg_image, .stat_size = _stat_size_nrg, }; @@ -1230,23 +1202,32 @@ cdio_open_nrg (const char *psz_source) _data->is_dao = false; _data->is_cues = false; /* FIXME: remove is_cues. */ - _set_arg_nrg(_data, "source", (NULL == psz_source) - ? DEFAULT_CDIO_DEVICE: psz_source); - ret = cdio_new (_data, &_funcs); - if (ret == NULL) return NULL; - - if (!cdio_is_nrg(psz_source)) { - cdio_debug ("source name %s is not recognized as a NRG image", - psz_source); + if (ret == NULL) { + free(_data); return NULL; } + _set_arg_image(_data, "source", (NULL == psz_source) + ? DEFAULT_CDIO_DEVICE: psz_source); + + _data->psz_cue_name = strdup(_get_arg_image(_data, "source")); + + if (!cdio_is_nrg(_data->psz_cue_name)) { + cdio_debug ("source name %s is not recognized as a NRG image", + _data->psz_cue_name); + _free_nrg(_data); + return NULL; + } + + _set_arg_image (_data, "cue", _data->psz_cue_name); + if (_init_nrg(_data)) return ret; else { _free_nrg(_data); + free(ret); return NULL; } diff --git a/lib/image_common.h b/lib/image_common.h index c8299b92..2cf00135 100644 --- a/lib/image_common.h +++ b/lib/image_common.h @@ -1,5 +1,5 @@ /* - $Id: image_common.h,v 1.7 2004/07/10 02:17:59 rocky Exp $ + $Id: image_common.h,v 1.8 2004/07/10 11:06:00 rocky Exp $ Copyright (C) 2004 Rocky Bernstein @@ -18,11 +18,75 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* Common image routines. */ +/*! Common image routines. + + Because _img_private_t may vary over image formats, the routines are + included into the image drivers after _img_private_t is defined. In + order for the below routines to work, there is a large part of + _img_private_t that is common among image drivers. For example, see + image.h +*/ #ifndef __CDIO_IMAGE_COMMON_H__ #define __CDIO_IMAGE_COMMON_H__ +#define free_if_notnull(obj) \ + if (NULL != obj) { free(obj); obj=NULL; }; + +/*! + We don't need the image any more. Free all memory associated with + it. + */ +static void +_free_image (void *user_data) +{ + _img_private_t *cd = user_data; + track_t i_track; + + if (NULL == cd) return; + + for (i_track=0; i_track < cd->i_tracks; i_track++) { + free_if_notnull(cd->tocent[i_track].filename); + free_if_notnull(cd->tocent[i_track].isrc); + cdtext_delete(cd->tocent[i_track].cdtext); + } + + free_if_notnull(cd->psz_mcn); + free_if_notnull(cd->psz_cue_name); + cdtext_delete(cd->cdtext); + cdio_generic_stdio_free(cd); + free(cd); +} + +/*! + Eject media -- there's nothing to do here except free resources. + We always return 2. + */ +static int +_eject_media_image(void *user_data) +{ + _free_image (user_data); + return 2; +} + +/*! + Return the value associated with the key "arg". +*/ +static const char * +_get_arg_image (void *user_data, const char key[]) +{ + _img_private_t *env = user_data; + + if (!strcmp (key, "source")) { + return env->gen.source_name; + } else if (!strcmp (key, "cue")) { + return env->psz_cue_name; + } else if (!strcmp(key, "access-mode")) { + return "image"; + } + return NULL; +} + /*! Return the media catalog number (MCN) from the CD or NULL if there is none or we don't have the ability to get it. @@ -75,8 +139,7 @@ _get_first_track_num_image(void *user_data) } /*! - Return the number of tracks. We fake it an just say there's - one big track. + Return the number of tracks. */ static track_t _get_num_tracks_image(void *user_data) @@ -86,4 +149,40 @@ _get_num_tracks_image(void *user_data) return env->i_tracks; } +/*! + Set the arg "key" with "value" in the source device. + Currently "source" to set the source device in I/O operations + is the only valid key. + + 0 is returned if no error was found, and nonzero if there as an error. +*/ +static int +_set_arg_image (void *user_data, const char key[], const char value[]) +{ + _img_private_t *env = user_data; + + if (!strcmp (key, "source")) + { + free_if_notnull (env->gen.source_name); + + if (!value) + return -2; + + env->gen.source_name = strdup (value); + } + else if (!strcmp (key, "cue")) + { + free_if_notnull (env->psz_cue_name); + + if (!value) + return -2; + + env->psz_cue_name = strdup (value); + } + else + return -1; + + return 0; +} + #endif /* __CDIO_IMAGE_COMMON_H__ */