From: <ny...@us...> - 2007-01-17 16:32:03
|
Revision: 265 http://svn.sourceforge.net/pmplib/?rev=265&view=rev Author: nyaochi Date: 2007-01-17 08:31:59 -0800 (Wed, 17 Jan 2007) Log Message: ----------- Incremental commit. Drastic change of the API. This revision broke playlist conversion for all players, music database construction for all players except for iriver E10. Modified Paths: -------------- trunk/pmplib/frontend/easypmp/common/database.c trunk/pmplib/frontend/easypmp/common/enumerate.c trunk/pmplib/frontend/easypmp/common/playlist.c trunk/pmplib/frontend/easypmp/cui/device.c trunk/pmplib/include/pmp.h trunk/pmplib/lib/pmp/pmp.c trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c Modified: trunk/pmplib/frontend/easypmp/common/database.c =================================================================== --- trunk/pmplib/frontend/easypmp/common/database.c 2007-01-16 16:38:24 UTC (rev 264) +++ trunk/pmplib/frontend/easypmp/common/database.c 2007-01-17 16:31:59 UTC (rev 265) @@ -111,6 +111,7 @@ int result = 0; uint32_t i; result_t res = 0; + ucs2char_t music_path[MAX_PATH]; pmp_music_t* pmpdb = pmp->music; pmp_music_record_t* records = NULL; pmp_music_record_t* old_records = NULL; @@ -121,6 +122,8 @@ return EASYPMPE_CANCEL; } + filepath_combinepath(music_path, MAX_PATH, pmp->info.path_to_root, pmp->info.path_to_music); + /* * Read the existing database for update processing mode. */ @@ -135,7 +138,7 @@ } // Obtain the number of records in the database. - res = pmpdb->get(pmpdb, NULL, &num_old_records); + res = pmpdb->get_records(pmpdb, NULL, &num_old_records); if (res != 0) { result = MAKE_PMP_ERROR(res); goto error_exit; @@ -149,7 +152,7 @@ } // Obtain the records from the database. - res = pmpdb->get(pmpdb, old_records, &num_old_records); + res = pmpdb->get_records(pmpdb, old_records, &num_old_records); if (res != 0) { result = MAKE_PMP_ERROR(res); goto error_exit; @@ -220,7 +223,7 @@ if (gmi_get( record, filename, - pmp->env.path_to_music.path, + music_path, opt->media_info_source, opt->strip_words, opt->num_strip_words @@ -242,7 +245,7 @@ result = EASYPMPE_CANCEL; goto error_exit; } - res = pmpdb->set(pmpdb, records, fl->num_elements); + res = pmpdb->set_records(pmpdb, records, fl->num_elements); if (res != 0) { result = MAKE_PMP_ERROR(res); goto error_exit; Modified: trunk/pmplib/frontend/easypmp/common/enumerate.c =================================================================== --- trunk/pmplib/frontend/easypmp/common/enumerate.c 2007-01-16 16:38:24 UTC (rev 264) +++ trunk/pmplib/frontend/easypmp/common/enumerate.c 2007-01-17 16:31:59 UTC (rev 265) @@ -39,11 +39,6 @@ #include <easypmp.h> -/** - * \addtogroup common - * @{ - */ - typedef struct { const option_t* opt; easypmp_filelist_t* fl; @@ -54,11 +49,20 @@ static int found_music_file(void *instance, const ucs2char_t* found_path, const ucs2char_t* found_file) { + uint32_t i; enumerate_dat_t* ed = (enumerate_dat_t*)instance; + pmp_t* pmp = ed->pmp; pmp_music_t* pmp_music = ed->pmp->music; easypmp_filelist_t* fl = ed->fl; - if (pmp_music->is_supported_ext(pmp_music, found_file)) { + // Check if the file has an extension supported by the target player. + for (i = 0;i < pmp->info.num_audio_extensions;++i) { + if (filepath_hasext(found_file, pmp->info.audio_extensions[i])) { + break; + } + } + + if (i != pmp->info.num_audio_extensions) { // Supported music file. easypmp_filename_t* new_filename = NULL; @@ -98,12 +102,10 @@ ) { enumerate_dat_t ed; + ucs2char_t music_path[MAX_PATH]; // Decode the music path prefix for system path separators - size_t prefix_length = ucs2len(pmp->env.path_to_music.path); - ucs2char_t *music_path = alloca(sizeof(ucs2char_t) * (prefix_length + 1)); - ucs2cpy(music_path, pmp->env.path_to_music.path); - + filepath_combinepath(music_path, MAX_PATH, pmp->info.path_to_root, pmp->info.path_to_music); filepath_decode(music_path); fl->num_elements = 0; @@ -118,7 +120,7 @@ return find_file( music_path, - pmp->env.path_to_music.flag & PMPPEF_RECURSIVE ? 1 : 0, + pmp->info.music_flag & PMPMF_RECURSIVE ? 1 : 0, found_music_file, &ed ); @@ -172,6 +174,7 @@ { int ret = 0; enumerate_dat_t ed; + ucs2char_t path[MAX_PATH]; fl->num_elements = 0; fl->elements = NULL; @@ -184,17 +187,23 @@ ed.instance = instance; if (opt->verb & MODE_PLAYLIST_PLAYLIST) { + // Decode the playlist path prefix for system path separators + filepath_combinepath(path, MAX_PATH, pmp->info.path_to_root, pmp->info.path_to_playlist); + filepath_decode(path); ret = find_file( - pmp->env.path_to_playlist.path, - pmp->env.path_to_playlist.flag & PMPPEF_RECURSIVE ? 1 : 0, + path, + pmp->info.playlist_flag & PMPPF_RECURSIVE ? 1 : 0, found_playlist_file, &ed ); } if (opt->verb & MODE_PLAYLIST_MUSIC) { + // Decode the playlist path prefix for system path separators + filepath_combinepath(path, MAX_PATH, pmp->info.path_to_root, pmp->info.path_to_music); + filepath_decode(path); ret = find_file( - pmp->env.path_to_music.path, - pmp->env.path_to_music.flag & PMPPEF_RECURSIVE ? 1 : 0, + path, + pmp->info.music_flag & PMPMF_RECURSIVE ? 1 : 0, found_playlist_file, &ed ); @@ -210,5 +219,3 @@ free(fl->elements); memset(fl, 0, sizeof(*fl)); } - -/** @} */ Modified: trunk/pmplib/frontend/easypmp/common/playlist.c =================================================================== --- trunk/pmplib/frontend/easypmp/common/playlist.c 2007-01-16 16:38:24 UTC (rev 264) +++ trunk/pmplib/frontend/easypmp/common/playlist.c 2007-01-17 16:31:59 UTC (rev 265) @@ -75,6 +75,7 @@ ) { int result = 0; + /* int i, j, num_succeeded = 0; char *mbs = NULL; pmp_playlist_t* pmppl = NULL; @@ -263,6 +264,7 @@ pmppl->release(pmppl); pmppl = NULL; } + */ return result; } /** @} */ Modified: trunk/pmplib/frontend/easypmp/cui/device.c =================================================================== --- trunk/pmplib/frontend/easypmp/cui/device.c 2007-01-16 16:38:24 UTC (rev 264) +++ trunk/pmplib/frontend/easypmp/cui/device.c 2007-01-17 16:31:59 UTC (rev 265) @@ -59,19 +59,17 @@ void device_show_information(pmp_t* pmp, FILE *fp) { - fprintf(fp, "Device identifier: %s\n", pmp->decl.id); - fprintf(fp, " Manufacturer: %s\n", pmp->decl.manufacturer); - fprintf(fp, " Product name: %s\n", pmp->decl.name); - fprintf(fp, " Firmware mode: %s\n", pmp->decl.mode); - fprintf(fp, " Firmware version: %s\n", pmp->decl.version); - fprintf(fp, " Firmware range: %s to %s\n", pmp->decl.min_version, pmp->decl.max_version); - fprintf(fp, " Default language: %s\n", pmp->decl.language); + fprintf(fp, "Device identifier: %s\n", pmp->info.decl.id); + fprintf(fp, " Manufacturer: %s\n", pmp->info.decl.manufacturer); + fprintf(fp, " Product name: %s\n", pmp->info.decl.name); + fprintf(fp, " Firmware mode: %s\n", pmp->info.decl.mode); + fprintf(fp, " Firmware version: %s\n", pmp->info.decl.version); + fprintf(fp, " Firmware range: %s to %s\n", pmp->info.decl.min_version, pmp->info.decl.max_version); + fprintf(fp, " Default language: %s\n", pmp->info.decl.language); - fprints(fp, " Root directory: %s\n", pmp->env.path_to_root.path); - device_show_path(fp, " Music directory: %s\n", pmp->env.path_to_music.path); - device_show_path(fp, " Playlist directory: %s\n", pmp->env.path_to_playlist.path); - - fprints(fp, " Playlist extension: %s\n", pmp->env.playlist_ext); + fprints(fp, " Root directory: %s\n", pmp->info.path_to_root); + device_show_path(fp, " Music directory: %s\n", pmp->info.path_to_music); + device_show_path(fp, " Playlist directory: %s\n", pmp->info.path_to_playlist); } static void enumerate_devid_callback(void *instance, const char *devid) Modified: trunk/pmplib/include/pmp.h =================================================================== --- trunk/pmplib/include/pmp.h 2007-01-16 16:38:24 UTC (rev 264) +++ trunk/pmplib/include/pmp.h 2007-01-17 16:31:59 UTC (rev 265) @@ -53,7 +53,6 @@ */ struct tag_pmp_t; typedef struct tag_pmp_t pmp_t; struct tag_pmp_music_t; typedef struct tag_pmp_music_t pmp_music_t; -struct tag_pmp_playlist_t; typedef struct tag_pmp_playlist_t pmp_playlist_t; /** * Error codes. @@ -109,11 +108,15 @@ #define PMPFOURCC(a, b, c, d) \ ((uint32_t)(a) << 24 | (uint32_t)(b) << 16 | (uint32_t)(c) << 8 | (uint32_t)(d)) +#define PMPCODEC_NONE PMPFOURCC(' ',' ',' ',' ') #define PMPCODEC_MPEGLAYER3 PMPFOURCC('M','P','1','3') /**< MPEG Audio Layer III */ #define PMPCODEC_WMA PMPFOURCC('W','M','A',' ') /**< Windows Media Audio */ #define PMPCODEC_VORBIS PMPFOURCC('O','V','1',' ') /**< Ogg Vorbis */ #define PMPCODEC_WAV PMPFOURCC('W','A','V','E') /**< Microsoft Riff WAVE */ +#define PMPMAXCODECS 32 +#define PMPMAXEXT 8 + enum { PMPPEF_NONE = 0x0000, PMPPEF_SUPPORT = 0x0001, @@ -121,11 +124,19 @@ PMPPEF_RECURSIVE = 0x0004, }; -typedef struct { - int flag; - ucs2char_t path[MAX_PATH]; -} pmp_pathenv_t; +enum { + PMPMF_NONE = 0x0000, + PMPMF_SUPPORT = 0x0001, + PMPMF_RECURSIVE = 0x0002, +}; +enum { + PMPPF_NONE = 0x0000, + PMPPF_SUPPORT = 0x0001, + PMPPF_RECURSIVE = 0x0002, +}; + + /** Maximum size, in chars, of a device description. */ #define PMP_DECLSIZE (128) /** Unavailable field of a device description. */ @@ -133,7 +144,7 @@ /** * PMP device decription. - * This structure stores information about a PMP device. An PMP device driver + * This structure stores information about a PMP device. A PMP device driver * should fill these fields properly so that an application can obtain the * information about the device. An empty value represents the uncertainity * of the field value at this stage. The value ::PMP_DECLUNAVAIL (\c "***") @@ -160,18 +171,39 @@ /** * PMP device environment. - * This structure stores + * This structure stores information about predefined paths, capability, */ typedef struct { - pmp_pathenv_t path_to_root; /**< Path to the root directory */ - pmp_pathenv_t path_to_music; /**< Path to the music files */ - pmp_pathenv_t path_to_playlist; /**< Path to the playlist files */ - pmp_pathenv_t path_to_photo; /**< Path to the photo files */ - ucs2char_t playlist_ext[MAX_PATH]; -} pmp_device_environment_t; + /** Path to the root directory of the player. */ + ucs2char_t path_to_root[MAX_PATH]; + /** Relative path to the system directory from the root. */ + ucs2char_t path_to_system[MAX_PATH]; + /** Relative path to the music directory from the root. */ + ucs2char_t path_to_music[MAX_PATH]; + /** Relative path to the playlist directory from the root. */ + ucs2char_t path_to_playlist[MAX_PATH]; + /** Music flags. */ + uint32_t music_flag; + /** Playlist flags. */ + uint32_t playlist_flag; + /** Number of elements in \a audio_codecs array. */ + uint32_t num_audio_codecs; + /** Array of PMPFOURCC values corresponding to the supported audio codecs. */ + uint32_t* audio_codecs; + /** Number of elements in \a audio_extensions array. */ + uint32_t num_audio_extensions; + /** Array of ucs2char_t string values for audio file extensions. */ + ucs2char_t** audio_extensions; + + /** Description about the device. */ + const pmp_device_description_t decl; +} pmp_device_information_t; + + + /** * The root interface for portable media device. * This structure represents the basic interface that is common to any @@ -206,12 +238,10 @@ */ uint32_t flag; - pmp_device_description_t decl; - /** - * Portable media device environment. + * PMP device decription. */ - pmp_device_environment_t env; + pmp_device_information_t info; /** * The pointer to pmp_music_t interface. @@ -220,7 +250,7 @@ /** * Increment the reference counter. - * @param pmp Ths pointer to the pmp_t instance. + * @param pmp The pointer to the pmp_t instance. */ uint32_t (*add_ref)(pmp_t* pmp); @@ -228,14 +258,23 @@ * Decrement the reference counter. * If the reference counter becomes zero after this decrement, * this function will destroy the pmp_t instance. - * @param pmp Ths pointer to the pmp_t instance. + * @param pmp The pointer to the pmp_t instance. */ uint32_t (*release)(pmp_t* pmp); + /** + * Open the PMP device. + * @param pmp The pointer to the pmp_t instance. + * @param flag The open flags. + */ result_t (*open)(pmp_t* pmp, uint32_t flag); + + /** + * Close the PMP device. + * @param pmp The pointer to the pmp_t instance. + * @param flag The close flags. + */ result_t (*close)(pmp_t* pmp, uint32_t flag); - - result_t (*create_instance_pl)(pmp_t* pmp, pmp_playlist_t** pmppl); }; typedef void pmpdb_readwrite_progress_t(void *instance, uint32_t size, uint32_t total); @@ -265,30 +304,28 @@ }; typedef struct tag_pmp_music_record_t pmp_music_record_t; +typedef struct { + ucs2char_t filename[MAX_PATH]; +} pmp_playlist_entry_t; + +typedef struct { + ucs2char_t name[MAX_PATH]; + int num_entries; + pmp_playlist_entry_t* entries; +} pmp_playlist_t; + struct tag_pmp_music_t { void* instance; pmp_t* pmp; - result_t (*set)(pmp_music_t* pmpdb, const pmp_music_record_t* records, uint32_t num_records); - result_t (*get)(pmp_music_t* pmpdb, pmp_music_record_t* records, uint32_t* num_records); + result_t (*set_records)(pmp_music_t* pmpdb, const pmp_music_record_t* records, uint32_t num_records); + result_t (*get_records)(pmp_music_t* pmpdb, pmp_music_record_t* records, uint32_t* num_records); + result_t (*set_playlists)(pmp_music_t* pmpdb, const pmp_playlist_t* playlists, uint32_t num_playlists); result_t (*dump)(pmp_music_t* pmpdb, FILE *fp, int level); - - int (*is_supported_codec)(pmp_music_t* pmpdb, uint32_t codec); - int (*is_supported_ext)(pmp_music_t* pmpdb, const ucs2char_t* filename); }; -struct tag_pmp_playlist_t { - void* instance; - uint32_t ref_count; - pmp_t* pmp; - uint32_t (*add_ref)(pmp_playlist_t* pmppl); - uint32_t (*release)(pmp_playlist_t* pmppl); - - result_t (*write)(pmp_playlist_t* pmppl, const ucs2char_t* filename, ucs2char_t * const files[], uint32_t num_files); -}; - typedef result_t (*pmp_create_t)(pmp_t** pmp, const ucs2char_t* path_to_device, const char *devid); /** @@ -303,7 +340,6 @@ PMPAPI result_t pmp_record_copy(pmp_music_record_t* dst, const pmp_music_record_t* src); PMPAPI uint32_t pmp_interlocked_increment(uint32_t* count); PMPAPI uint32_t pmp_interlocked_decrement(uint32_t* count); -PMPAPI void pmp_copy_environment(pmp_device_environment_t* dst, const pmp_device_environment_t* src); Modified: trunk/pmplib/lib/pmp/pmp.c =================================================================== --- trunk/pmplib/lib/pmp/pmp.c 2007-01-16 16:38:24 UTC (rev 264) +++ trunk/pmplib/lib/pmp/pmp.c 2007-01-17 16:31:59 UTC (rev 265) @@ -62,8 +62,3 @@ dst->date = src->date ? ucs2dup(src->date) : NULL; return 0; } - -void pmp_copy_environment(pmp_device_environment_t* dst, const pmp_device_environment_t* src) -{ - memcpy(dst, src, sizeof(*src)); -} Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2007-01-16 16:38:24 UTC (rev 264) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2007-01-17 16:31:59 UTC (rev 265) @@ -56,6 +56,9 @@ const char *dat_filename; const char *dic_filename; const char *idx_filename; + const char *extensions; + uint32_t codecs[8]; + const char *path_to_system; const char *path_to_music; const char *path_to_playlist; const char *playlist_ext; @@ -63,154 +66,155 @@ static const ip3model_descriptor_t g_model_descriptions[] = { { - "iriver_e10_ums_1.00-1.04", "iriver", "E10 UMS", "UM", - "1.00", "1.04", + "iriver_e10_ums_1.0-1.4", "iriver", "E10 UMS", "UM", + "1.0", "1.4", "System\\E10.SYS", "System\\db.dat", "System\\db.dic", "System\\db.idx", - "", "Playlists\\", + ".mp3\0.ogg\0.wma\0.wav\0", + {PMPCODEC_MPEGLAYER3, PMPCODEC_VORBIS, PMPCODEC_WMA, PMPCODEC_WAV, 0, 0, 0, 0}, + "System\\", "", "Playlists\\", ".plp", }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, + {0, 0, 0, 0, 0, 0, 0, 0}, NULL, NULL, NULL, }, }; typedef struct { - char id[128]; - char name[128]; - char mode[128]; - char language[128]; - char version[128]; - - ucs2char_t path_to_root[MAX_PATH]; - ucs2char_t path_to_music[MAX_PATH]; - ucs2char_t path_to_playlist[MAX_PATH]; - ucs2char_t sys_filename[MAX_PATH]; - ucs2char_t dat_filename[MAX_PATH]; - ucs2char_t dic_filename[MAX_PATH]; - ucs2char_t idx_filename[MAX_PATH]; - ucs2char_t playlist_ext[MAX_PATH]; -} ip3_environment_t; - - -typedef struct { - ip3_environment_t env; + const ip3model_descriptor_t* decl; } pmp_internal_t; -typedef struct { - ip3db_t ip3db; -} pmpdb_internal_t; - -typedef struct { - ip3db_t ip3db; -} pmppl_internal_t; - - static uint32_t pmp_add_ref(pmp_t* pmp); static uint32_t pmp_release(pmp_t* pmp); static result_t pmp_open(pmp_t* pmp, uint32_t flag); static result_t pmp_close(pmp_t* pmp, uint32_t flag); -static result_t pmp_create_instance_db(pmp_t* pmp, pmp_music_t** ptr_pmpdb); -static result_t pmp_create_instance_pl(pmp_t* pmp, pmp_playlist_t** ptr_pmppl); +static result_t pmp_create_instance_music(pmp_t* pmp, pmp_music_t** ptr_pmpdb); -static uint32_t pmpdb_release(pmp_music_t* pmpdb); -static result_t pmpdb_read(pmp_music_t* pmpdb); -static result_t pmpdb_write(pmp_music_t* pmpdb); -static result_t pmpdb_set(pmp_music_t* pmpdb, const pmp_music_record_t* records, uint32_t num_records); -static result_t pmpdb_get(pmp_music_t* pmpdb, pmp_music_record_t* records, uint32_t* num_records); -static result_t pmpdb_dump(pmp_music_t* pmpdb, FILE *fp, int level); -static int pmpdb_is_supported_codec(pmp_music_t* pmpdb, uint32_t codec); -static int pmpdb_is_supported_ext(pmp_music_t* pmpdb, const ucs2char_t* filename); +static uint32_t pmpmusic_release(pmp_music_t* pmpdb); +static result_t pmpmusic_set_records(pmp_music_t* pmpdb, const pmp_music_record_t* records, uint32_t num_records); +static result_t pmpmusic_get_records(pmp_music_t* pmpdb, pmp_music_record_t* records, uint32_t* num_records); +static result_t pmpmusic_dump(pmp_music_t* pmpdb, FILE *fp, int level); +static result_t pmpmusic_set_playlists(pmp_music_t* pmpdb, const pmp_playlist_t* playlists, uint32_t num_playlists); -static uint32_t pmppl_add_ref(pmp_playlist_t* pmppl); -static uint32_t pmppl_release(pmp_playlist_t* pmppl); -static result_t pmppl_write(pmp_playlist_t* pmppl, const ucs2char_t* filename, ucs2char_t* const files[], uint32_t num_files); +#define COMP(a, b) ((a)>(b))-((a)<(b)) -static void set_environment( - ip3_environment_t* env, +static char* strip(char *str) +{ + char *p = str + strlen(str) - 1; + while (*str && isspace(*str)) { + str++; + } + while (str <= p && isspace(*p)) { + *p-- = 0; + } + return str; +} + +static const char *strcpy_if_empty(char *dst, const char *src) +{ + return *dst ? dst : strcpy(dst, src); +} + +static void set_device_info( + const char *id, + const ucs2char_t* path_to_device, const ip3model_descriptor_t* md, - const ucs2char_t* path_to_device + pmp_device_information_t* info ) { + uint32_t n; + const char *p = NULL; ucs2char_t* ucs2 = NULL; + pmp_device_description_t* decl = (pmp_device_description_t*)&info->decl; - ucs2cpy(env->path_to_root, path_to_device); + strcpy_if_empty(decl->id, id); + strcpy_if_empty(decl->manufacturer, md->manufacturer); + strcpy_if_empty(decl->name, md->name); + strcpy_if_empty(decl->mode, md->mode); + //strcpy_if_empty(decl->language, md->language); + //strcpy_if_empty(decl->version, md->version); + strcpy_if_empty(decl->min_version, md->min_version); + strcpy_if_empty(decl->max_version, md->max_version); - ucs2cpy(env->path_to_music, path_to_device); - filepath_addslash(env->path_to_music); + ucs2cpy(info->path_to_root, path_to_device); + + ucs2 = mbsdupucs2(md->path_to_system); + ucs2cpy(info->path_to_system, ucs2); + ucs2free(ucs2); + ucs2 = mbsdupucs2(md->path_to_music); - ucs2cat(env->path_to_music, ucs2); + ucs2cpy(info->path_to_music, ucs2); ucs2free(ucs2); - ucs2cpy(env->path_to_playlist, path_to_device); - filepath_addslash(env->path_to_playlist); ucs2 = mbsdupucs2(md->path_to_playlist); - ucs2cat(env->path_to_playlist, ucs2); + ucs2cpy(info->path_to_playlist, ucs2); ucs2free(ucs2); - ucs2cpy(env->sys_filename, path_to_device); - filepath_addslash(env->sys_filename); - ucs2 = mbsdupucs2(md->sys_filename); - ucs2cat(env->sys_filename, ucs2); - ucs2free(ucs2); + info->music_flag = PMPMF_SUPPORT | PMPMF_RECURSIVE; + info->playlist_flag = PMPPF_SUPPORT; - ucs2cpy(env->dat_filename, path_to_device); - filepath_addslash(env->dat_filename); - ucs2 = mbsdupucs2(md->dat_filename); - ucs2cat(env->dat_filename, ucs2); - ucs2free(ucs2); + // Audio codecs. + for (n = 0;md->codecs[n];++n) ; + info->num_audio_codecs = n; + info->audio_codecs = (uint32_t*)ucs2malloc(sizeof(uint32_t) * info->num_audio_codecs); + for (n = 0;n < info->num_audio_codecs;++n) { + info->audio_codecs[n] = md->codecs[n]; + } - ucs2cpy(env->dic_filename, path_to_device); - filepath_addslash(env->dic_filename); - ucs2 = mbsdupucs2(md->dic_filename); - ucs2cat(env->dic_filename, ucs2); - ucs2free(ucs2); + // Obtain the number of extensions separated by '\0' characters. + for (n = 0, p = md->extensions;*p;p += (strlen(p)+1)) { + n++; + } + info->num_audio_extensions = n; + info->audio_extensions = (ucs2char_t*)ucs2malloc(sizeof(ucs2char_t*) * info->num_audio_extensions); + for (n = 0, p = md->extensions;*p;p += (strlen(p)+1)) { + info->audio_extensions[n++] = mbsdupucs2(p); + } - ucs2cpy(env->idx_filename, path_to_device); - filepath_addslash(env->idx_filename); - ucs2 = mbsdupucs2(md->idx_filename); - ucs2cat(env->idx_filename, ucs2); - ucs2free(ucs2); - ucs2 = mbsdupucs2(md->playlist_ext); - ucs2cat(env->playlist_ext, ucs2); - ucs2free(ucs2); } -static int match_model( - const char *id, - const ucs2char_t* path_to_device, - const ip3model_descriptor_t* md, - ip3_environment_t* env - ) +static void free_device_info(pmp_device_information_t* info) { - memset(env, 0, sizeof(*env)); - - if (!id || strcmp(md->id, id) != 0) { - return 0; + uint32_t i; + for (i = 0;i < info->num_audio_extensions;++i) { + ucs2free(info->audio_extensions[i]); } - - set_environment(env, md, path_to_device); - return 1; + ucs2free(info->audio_codecs); + ucs2free(info->audio_extensions); + memset(info, 0, sizeof(*info)); } -static char* strip(char *str) +static void set_filenames(ucs2char_t *dat, ucs2char_t *dic, ucs2char_t *idx, pmp_t *pmp) { - char *p = str + strlen(str) - 1; - while (*str && isspace(*str)) { - str++; - } - while (str <= p && isspace(*p)) { - *p-- = 0; - } - return str; + ucs2char_t* ucs2 = NULL; + pmp_internal_t* pmpi = (pmp_internal_t*)pmp->instance; + + ucs2cpy(dat, pmp->info.path_to_root); + filepath_addslash(dat); + ucs2 = mbsdupucs2(pmpi->decl->dat_filename); + ucs2cat(dat, ucs2); + ucs2free(ucs2); + + ucs2cpy(dic, pmp->info.path_to_root); + filepath_addslash(dic); + ucs2 = mbsdupucs2(pmpi->decl->dic_filename); + ucs2cat(dic, ucs2); + ucs2free(ucs2); + + ucs2cpy(idx, pmp->info.path_to_root); + filepath_addslash(idx); + ucs2 = mbsdupucs2(pmpi->decl->idx_filename); + ucs2cat(idx, ucs2); + ucs2free(ucs2); } -#define COMP(a, b) ((a)>(b))-((a)<(b)) static int compare_version(const char *x, const char *y) { @@ -234,19 +238,23 @@ static int detect_model( const ucs2char_t* path_to_device, const ip3model_descriptor_t* md, - ip3_environment_t* env + pmp_device_information_t* ptr_info ) { ucs2char_t* ucs2 = NULL; ucs2char_t filename[MAX_PATH]; + pmp_device_description_t decl; - memset(env, 0, sizeof(*env)); + memset(&decl, 0, sizeof(decl)); + // filename = "${path_to_device}/${md->sys_filename}" ucs2cpy(filename, path_to_device); filepath_addslash(filename); ucs2 = mbsdupucs2(md->sys_filename); ucs2cat(filename, ucs2); ucs2free(ucs2); + + // Check the existence of the system file. if (filepath_file_exists(filename)) { int match = 1; char line[128]; @@ -259,32 +267,25 @@ char *p = strip(line); if (p[0] == '[' && line[strlen(p)-1] == ']') { p[strlen(p)-1] = 0; - strcpy(env->name, p+1); + strcpy(decl.name, p+1); } else if (strncmp(p, "version = ", 10) == 0) { - /* They are too stupid to describe version "1.04" as "1.4" */ - if (strlen(p+10) == 3 && p[11] == '.') { - env->version[0] = p[10]; - env->version[1] = p[11]; - env->version[2] = '0'; - env->version[3] = p[12]; - env->version[4] = 0; - } else { - strcpy(env->version, p+10); - } + strcpy(decl.version, p+10); } else if (strncmp(p, "language = ", 11) == 0) { - strcpy(env->language, p+11); + strcpy(decl.language, p+11); } else if (strncmp(p, "mode = ", 7) == 0) { - strcpy(env->mode, p+7); + strcpy(decl.mode, p+7); } } + fclose(fp); - match &= (strcmp(env->mode, md->mode) == 0); - match &= (compare_version(md->min_version, env->version) <= 0); - match &= (compare_version(env->version, md->max_version) <= 0); + // Test the compability of the device. + match &= (strcmp(decl.mode, md->mode) == 0); + match &= (compare_version(md->min_version, decl.version) <= 0); + match &= (compare_version(decl.version, md->max_version) <= 0); if (match) { - set_environment(env, md, path_to_device); + memcpy((pmp_device_description_t*)&ptr_info->decl, &decl, sizeof(decl)); return 1; } } @@ -308,25 +309,32 @@ pmp_t* pmp = NULL; pmp_internal_t* pmpi = NULL; const ip3model_descriptor_t* md = NULL; - ip3_environment_t env; - pmp_device_environment_t* pmpenv = NULL; + pmp_device_information_t info; + // Initialize device information. + memset(&info, 0, sizeof(info)); + + // Return a NULL pointer by default. *ptr_pmp = 0; // Find a suitable model for the device. md = g_model_descriptions; for (;md->id;++md) { - if (detect_model(path_to_device, md, &env)) { - if (!id || !id[0]) { + if (id && *id) { + // Match the device identifier. + if (strcmp(md->id, id) == 0) { + // This will fill some members in decl. + detect_model(path_to_device, md, &info); + set_device_info(id, path_to_device, md, &info); break; } - if (strcmp(md->id, id) == 0) { + } else { + // Detect the model automatically. + if (detect_model(path_to_device, md, &info)) { + set_device_info(md->id, path_to_device, md, &info); break; } } - if (match_model(id, path_to_device, md, &env)) { - break; - } } if (!md->id) { return PMP_DEVICENOTFOUND; @@ -342,7 +350,6 @@ pmp->release = pmp_release; pmp->open = pmp_open; pmp->close = pmp_close; - pmp->create_instance_pl = pmp_create_instance_pl; pmp->add_ref(pmp); // Allocate the internal variables. @@ -351,32 +358,14 @@ free(pmp); return PMPDBE_OUTOFMEMORY; } - pmp->instance = pmpi; + pmpi->decl = md; // Initialize the internal variables. - memcpy(&pmpi->env, &env, sizeof(env)); + pmp->instance = pmpi; + memcpy((pmp_device_information_t*)&pmp->info, &info, sizeof(info)); - // Initialize the (exportable) env. - strcpy(pmp->decl.id, md->id); - strcpy(pmp->decl.manufacturer, md->manufacturer); - strcpy(pmp->decl.name, md->name); - strcpy(pmp->decl.mode, md->mode); - strcpy(pmp->decl.language, pmpi->env.language); - strcpy(pmp->decl.version, pmpi->env.version); - strcpy(pmp->decl.min_version, md->min_version); - strcpy(pmp->decl.max_version, md->max_version); - - pmpenv = &pmp->env; - pmpenv->path_to_root.flag = PMPPEF_SUPPORT | PMPPEF_CONSTANT; - ucs2cpy(pmpenv->path_to_root.path, pmpi->env.path_to_root); - pmpenv->path_to_music.flag = PMPPEF_SUPPORT | PMPPEF_RECURSIVE; - ucs2cpy(pmpenv->path_to_music.path, pmpi->env.path_to_music); - pmpenv->path_to_playlist.flag = PMPPEF_SUPPORT; - ucs2cpy(pmpenv->path_to_playlist.path, pmpi->env.path_to_playlist); - ucs2cpy(pmpenv->playlist_ext, pmpi->env.playlist_ext); - // Create music instance. - ret = pmp_create_instance_db(pmp, &pmp->music); + ret = pmp_create_instance_music(pmp, &pmp->music); if (ret != 0) { pmp_release(pmp); return ret; @@ -396,7 +385,8 @@ { uint32_t count = pmp_interlocked_decrement(&pmp->ref_count); if (count == 0) { - pmpdb_release(pmp->music); + pmpmusic_release(pmp->music); + free_device_info(&pmp->info); free(pmp->instance); free(pmp); } @@ -409,10 +399,11 @@ pmp->flag = flag; if (pmp->flag & PMPOF_MUSIC_DB_READ) { - ret = pmpdb_read(pmp->music); - if (ret != 0) { - return ret; - } + ucs2char_t dat[MAX_PATH], dic[MAX_PATH], idx[MAX_PATH]; + ip3db_t* ip3db = (ip3db_t*)pmp->music->instance; + + set_filenames(dat, dic, idx, pmp); + return ip3db_read(ip3db, dat, dic, idx); } return 0; } @@ -421,76 +412,43 @@ { result_t ret = 0; if (pmp->flag & PMPOF_MUSIC_DB_WRITE) { - ret = pmpdb_write(pmp->music); - if (ret != 0) { - return ret; - } - } - return 0; -} + ucs2char_t dat[MAX_PATH], dic[MAX_PATH], idx[MAX_PATH]; + ip3db_t* ip3db = (ip3db_t*)pmp->music->instance; -static result_t pmp_create_instance_db(pmp_t* pmp, pmp_music_t** ptr_pmpdb) -{ - pmp_music_t* pmpdb = NULL; - pmp_internal_t* pmpi = (pmp_internal_t*)pmp->instance; - pmpdb_internal_t* pmpdbi = NULL; - - *ptr_pmpdb = 0; - - pmpdb = calloc(1, sizeof(pmp_music_t)); - if (!pmpdb) { - return PMPDBE_OUTOFMEMORY; + set_filenames(dat, dic, idx, pmp); + return ip3db_write(ip3db, dat, dic, idx); } - - pmpdb->set = pmpdb_set; - pmpdb->get = pmpdb_get; - pmpdb->dump = pmpdb_dump; - pmpdb->is_supported_codec = pmpdb_is_supported_codec; - pmpdb->is_supported_ext = pmpdb_is_supported_ext; - - pmpdbi = calloc(1, sizeof(pmpdb_internal_t)); - if (!pmpdbi) { - free(pmpdb); - return PMPDBE_OUTOFMEMORY; - } - ip3db_init(&pmpdbi->ip3db); - - pmpdb->pmp = pmp; - pmpdb->instance = pmpdbi; - - *ptr_pmpdb = pmpdb; return 0; } -static result_t pmp_create_instance_pl(pmp_t* pmp, pmp_playlist_t** ptr_pmppl) +static result_t pmp_create_instance_music(pmp_t* pmp, pmp_music_t** ptr_music) { + ip3db_t* ip3db = NULL; + pmp_music_t* music = NULL; pmp_internal_t* pmpi = (pmp_internal_t*)pmp->instance; - pmp_playlist_t* pmppl = NULL; - pmppl_internal_t* pmppli = NULL; - *ptr_pmppl = 0; + *ptr_music = 0; - pmppl = calloc(1, sizeof(pmp_playlist_t)); - if (!pmppl) { + music = calloc(1, sizeof(pmp_music_t)); + if (!music) { return PMPDBE_OUTOFMEMORY; } - pmppl->add_ref = pmppl_add_ref; - pmppl->release = pmppl_release; - pmppl->write = pmppl_write; - - pmppli = calloc(1, sizeof(pmppl_internal_t)); - if (!pmppli) { - free(pmppl); + ip3db = calloc(1, sizeof(ip3db_t)); + if (!ip3db) { + free(music); return PMPDBE_OUTOFMEMORY; } - ip3db_init(&pmppli->ip3db); - ip3db_read(&pmppli->ip3db, pmpi->env.dat_filename, pmpi->env.dic_filename, pmpi->env.idx_filename); + ip3db_init(ip3db); - pmppl->pmp = pmp; - pmppl->instance = pmppli; + music->set_records = pmpmusic_set_records; + music->get_records = pmpmusic_get_records; + music->dump = pmpmusic_dump; + music->set_playlists = pmpmusic_set_playlists; + music->pmp = pmp; + music->instance = ip3db; - *ptr_pmppl = pmppl; + *ptr_music = music; return 0; } @@ -498,39 +456,15 @@ -static uint32_t pmpdb_release(pmp_music_t* pmpdb) +static uint32_t pmpmusic_release(pmp_music_t* pmpmusic) { - pmpdb_internal_t* pmpdbi = (pmpdb_internal_t*)pmpdb->instance; - ip3db_finish(&pmpdbi->ip3db); - free(pmpdb->instance); - free(pmpdb); + ip3db_t* ip3db = (ip3db_t*)pmpmusic->instance; + ip3db_finish(ip3db); + free(pmpmusic->instance); + free(pmpmusic); return 0; } -static result_t pmpdb_read(pmp_music_t* pmpdb) -{ - pmpdb_internal_t* pmpdbi = (pmpdb_internal_t*)pmpdb->instance; - pmp_internal_t* pmpi = (pmp_internal_t*)pmpdb->pmp->instance; - return ip3db_read( - &pmpdbi->ip3db, - pmpi->env.dat_filename, - pmpi->env.dic_filename, - pmpi->env.idx_filename - ); -} - -static result_t pmpdb_write(pmp_music_t* pmpdb) -{ - pmpdb_internal_t* pmpdbi = (pmpdb_internal_t*)pmpdb->instance; - pmp_internal_t* pmpi = (pmp_internal_t*)pmpdb->pmp->instance; - return ip3db_write( - &pmpdbi->ip3db, - pmpi->env.dat_filename, - pmpi->env.dic_filename, - pmpi->env.idx_filename - ); -} - static ucs2char_t* _filepath_removeslash(ucs2char_t* path) { size_t length = ucs2len(path)-1; @@ -541,10 +475,11 @@ return (path + length); } -static result_t pmpdb_set(pmp_music_t* pmpdb, const pmp_music_record_t* records, uint32_t num_records) +static result_t pmpmusic_set_records(pmp_music_t* pmpdb, const pmp_music_record_t* records, uint32_t num_records) { - int i; - pmpdb_internal_t* pmpdbi = (pmpdb_internal_t*)pmpdb->instance; + uint32_t i; + pmp_t* pmp = pmpdb->pmp; + ip3db_t* ip3db = (ip3db_t*)pmpdb->instance; pmp_internal_t* pmpi = (pmp_internal_t*)pmpdb->pmp->instance; ip3db_music_record_t* array = (ip3db_music_record_t*)malloc(sizeof(ip3db_music_record_t) * num_records); @@ -552,8 +487,8 @@ const pmp_music_record_t* src = &records[i]; ip3db_variant_t* dst = array[i]; - ip3db_record_init(&pmpdbi->ip3db, &array[i]); - ip3db_variant_set_str(&dst[IP3DBF_MUSIC_FILEPATH], filepath_skipdrive(src->filename, pmpi->env.path_to_root)); + ip3db_record_init(ip3db, &array[i]); + ip3db_variant_set_str(&dst[IP3DBF_MUSIC_FILEPATH], filepath_skipdrive(src->filename, pmp->info.path_to_root)); filepath_remove_filespec(dst[IP3DBF_MUSIC_FILEPATH].value.str); filepath_addslash(dst[IP3DBF_MUSIC_FILEPATH].value.str); filepath_slash(dst[IP3DBF_MUSIC_FILEPATH].value.str); @@ -581,18 +516,18 @@ ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_UID], (uint32_t)i+1); } - ip3db_set(&pmpdbi->ip3db, array, num_records); + ip3db_set(ip3db, array, num_records); free(array); return 0; } -static result_t pmpdb_get(pmp_music_t* pmpdb, pmp_music_record_t* records, uint32_t* num_records) +static result_t pmpmusic_get_records(pmp_music_t* pmpdb, pmp_music_record_t* records, uint32_t* num_records) { - pmpdb_internal_t* pmpdbi = (pmpdb_internal_t*)pmpdb->instance; + pmp_t* pmp = pmpdb->pmp; + ip3db_t* ip3db = (ip3db_t*)pmpdb->instance; pmp_internal_t* pmpi = (pmp_internal_t*)pmpdb->pmp->instance; - ucs2char_t *path_to_root = alloca(sizeof(ucs2char_t) * (ucs2len(pmpi->env.path_to_root)+1)); - ip3db_t* db = &pmpdbi->ip3db; - int i, n = ip3db_num_records(db); + ucs2char_t *path_to_root = alloca(sizeof(ucs2char_t) * (ucs2len(pmp->info.path_to_root)+1)); + int i, n = ip3db_num_records(ip3db); if (!records) { *num_records = (uint32_t)n; @@ -600,17 +535,17 @@ } for (i = 0;i < n;++i) { - const ip3db_variant_t* src = (const ip3db_variant_t*)ip3db_get_record(db, i); + const ip3db_variant_t* src = (const ip3db_variant_t*)ip3db_get_record(ip3db, i); pmp_music_record_t* dst = &records[i]; size_t length = 0; pmp_record_init(dst); - length = ucs2len(pmpi->env.path_to_root); + length = ucs2len(pmp->info.path_to_root); length += ucs2len(src[IP3DBF_MUSIC_FILEPATH].value.str); length += ucs2len(src[IP3DBF_MUSIC_FILENAME].value.str); dst->filename = (ucs2char_t*)ucs2malloc(sizeof(ucs2char_t) * (length+1)); - ucs2cpy(dst->filename, pmpi->env.path_to_root); + ucs2cpy(dst->filename, pmp->info.path_to_root); ucs2cat(dst->filename, src[IP3DBF_MUSIC_FILEPATH].value.str+1); ucs2cat(dst->filename, src[IP3DBF_MUSIC_FILENAME].value.str); filepath_backslash(dst->filename); @@ -640,65 +575,25 @@ return 0; } -static result_t pmpdb_dump(pmp_music_t* pmpdb, FILE *fp, int level) +static result_t pmpmusic_dump(pmp_music_t* pmpmusic, FILE *fp, int level) { - pmpdb_internal_t* pmpdbi = (pmpdb_internal_t*)pmpdb->instance; + ip3db_t* ip3db = (ip3db_t*)pmpmusic->instance; if (level > 0) { return PMP_NOTIMPLIMENTED; //return ip2db_repr(&pmpdbi->ip2db, fp); } else { - return ip3db_dump(&pmpdbi->ip3db, fp); + return ip3db_dump(ip3db, fp); } } -static int pmpdb_is_supported_codec(pmp_music_t* pmpdb, uint32_t codec) +static result_t pmpmusic_set_playlists(pmp_music_t* pmpmusic, const pmp_playlist_t* playlists, uint32_t num_playlists) { - return ( - (codec == PMPCODEC_MPEGLAYER3) || - (codec == PMPCODEC_WMA) || - (codec == PMPCODEC_VORBIS) - ) ? 1 : 0; -} - -static int pmpdb_is_supported_ext(pmp_music_t* pmpdb, const ucs2char_t* filename) -{ - static const ucs2char_t ucs2cs_mp3[] = {'.','m','p','3',0}; - static const ucs2char_t ucs2cs_wma[] = {'.','w','m','a',0}; - static const ucs2char_t ucs2cs_ogg[] = {'.','o','g','g',0}; - - return ( - filepath_hasext(filename, ucs2cs_mp3) || - filepath_hasext(filename, ucs2cs_wma) || - filepath_hasext(filename, ucs2cs_ogg) - ) ? 1 : 0; -} - - - - - -static uint32_t pmppl_add_ref(pmp_playlist_t* pmppl) -{ - return pmp_interlocked_increment(&pmppl->ref_count); -} - -static uint32_t pmppl_release(pmp_playlist_t* pmppl) -{ - uint32_t count = pmp_interlocked_decrement(&pmppl->ref_count); - if (count == 0) { - pmppl_internal_t* pmppli = (pmppl_internal_t*)pmppl->instance; - free(pmppl->instance); - free(pmppl); - } - return count; -} - -static result_t pmppl_write(pmp_playlist_t* pmppl, const ucs2char_t* filename, ucs2char_t* const files[], uint32_t num_files) -{ + /* pmppl_internal_t* pmppli = (pmppl_internal_t*)pmppl->instance; pmp_internal_t* pmpi = (pmp_internal_t*)pmppl->pmp->instance; if (ip3db_playlist_write(&pmppli->ip3db, filename, files, num_files, pmpi->env.path_to_root) != 0) { return PMPPLE_WRITE; } + */ return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |