From: <ny...@us...> - 2007-01-26 07:55:54
|
Revision: 283 http://svn.sourceforge.net/pmplib/?rev=283&view=rev Author: nyaochi Date: 2007-01-25 23:55:48 -0800 (Thu, 25 Jan 2007) Log Message: ----------- Synchronize pmp_irivnavi with the latest API. Modified Paths: -------------- trunk/pmplib/lib/pmp_irivnavi/pmp_irivnavi.c Modified: trunk/pmplib/lib/pmp_irivnavi/pmp_irivnavi.c =================================================================== --- trunk/pmplib/lib/pmp_irivnavi/pmp_irivnavi.c 2007-01-26 03:44:58 UTC (rev 282) +++ trunk/pmplib/lib/pmp_irivnavi/pmp_irivnavi.c 2007-01-26 07:55:48 UTC (rev 283) @@ -67,6 +67,10 @@ {'S','y','s','t','e','m',PATHCHAR,'H','1','0','0','.','s','y','s',0}; static const ucs2char_t ucs2cs_system_h300_sys[] = {'S','y','s','t','e','m',PATHCHAR,'H','3','0','0','.','s','y','s',0}; +static const uint32_t g_codecs[] = + {PMPCODEC_MPEGLAYER3, PMPCODEC_VORBIS, PMPCODEC_WMA, PMPCODEC_WAV}; +static const char *g_music_exts[] = + {".mp3", ".ogg", ".wma", ".wav"}; #define MODELID_H100 "iriver_h100" #define MODELID_H300 "iriver_h300" @@ -83,28 +87,28 @@ irivnavi_environment_t env; } pmp_internal_t; +typedef struct { + irivnavi_t db; + pmp_music_record_t* records; + int num_records; + pmp_playlist_t* playlists; + int num_playlists; +} pmp_music_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_close(pmp_t* pmp); +static result_t pmp_create_instance_music(pmp_t* pmp, pmp_music_t** ptr_pmpdb); -static uint32_t pmpdb_add_ref(pmp_music_t* 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* music); +static uint32_t pmpmusic_open(pmp_music_t* music); +static result_t pmpmusic_close(pmp_music_t* music); +static result_t pmpmusic_set_records(pmp_music_t* music, const pmp_music_record_t* records, uint32_t num_records); +static result_t pmpmusic_get_records(pmp_music_t* music, pmp_music_record_t* records, uint32_t* num_records); +static result_t pmpmusic_dump(pmp_music_t* music, FILE *fp, int level); +static result_t pmpmusic_set_playlists(pmp_music_t* music, 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); - static int exists_sysfile(const ucs2char_t* path_to_device, const ucs2char_t* sysfilename) { ucs2char_t filename[MAX_PATH]; @@ -115,6 +119,17 @@ return filepath_file_exists(filename); } +static void free_device_info(pmp_device_information_t* info) +{ + uint32_t i; + for (i = 0;i < info->num_audio_extensions;++i) { + ucs2free(info->audio_extensions[i]); + } + ucs2free(info->audio_codecs); + ucs2free(info->audio_extensions); + memset(info, 0, sizeof(*info)); +} + PMPIRIVNAVIAPI result_t pmp_enumerate_devid(pmplib_enumerate_devid_callback_t callback, void *instance) { callback(instance, MODELID_H100); @@ -126,9 +141,11 @@ { int model = MODEL_NONE; result_t ret = 0; + size_t i = 0, n = 0; pmp_t* pmp = NULL; pmp_internal_t* pmpi = NULL; - pmp_device_environment_t* pmpenv = NULL; + pmp_device_information_t* info = NULL; + pmp_device_description_t* decl = NULL; *ptr_pmp = 0; @@ -173,7 +190,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. @@ -185,46 +201,49 @@ pmp->instance = pmpi; // Initialize the internal variables. - ucs2cpy(pmpi->env.path_to_root, path_to_device); - ucs2cpy(pmpi->env.path_to_music, path_to_device); // Force "\Music" directory for now. - filepath_addslash(pmpi->env.path_to_music); - ucs2cat(pmpi->env.path_to_music, ucs2cs_music_path); - ucs2cpy(pmpi->env.path_to_playlist, path_to_device); // Force "\Playlist" directory for now. - filepath_addslash(pmpi->env.path_to_playlist); - ucs2cat(pmpi->env.path_to_playlist, ucs2cs_playlist_path); - ucs2cpy(pmpi->env.playlist_ext, ucs2cs_playlist_ext); + info = &pmp->info; + decl = (pmp_device_description_t*)&info->decl; + ucs2cpy(info->path_to_root, path_to_device); + ucs2cpy(info->path_to_music, ucs2cs_music_path); // Force "\Music" directory for now. + ucs2cpy(info->path_to_playlist, ucs2cs_playlist_path); // Force "\Playlist" directory for now. + // Set model information. switch (model) { case MODEL_IRIVER_H100: - strcpy(pmp->decl.id, MODELID_H100); - strcpy(pmp->decl.manufacturer, "iriver"); - strcpy(pmp->decl.name, "H100 series"); + strcpy(decl->id, MODELID_H100); + strcpy(decl->manufacturer, "iriver"); + strcpy(decl->name, "H100 series"); break; case MODEL_IRIVER_H300: - strcpy(pmp->decl.id, MODELID_H300); - strcpy(pmp->decl.manufacturer, "iriver"); - strcpy(pmp->decl.name, "H300 series"); + strcpy(decl->id, MODELID_H300); + strcpy(decl->manufacturer, "iriver"); + strcpy(decl->name, "H300 series"); break; } - strcpy(pmp->decl.mode, "UM"); - strcpy(pmp->decl.language, PMP_DECLUNAVAIL); - strcpy(pmp->decl.version, PMP_DECLUNAVAIL); - strcpy(pmp->decl.max_version, PMP_DECLUNAVAIL); - strcpy(pmp->decl.min_version, PMP_DECLUNAVAIL); + strcpy(decl->mode, "UM"); + strcpy(decl->language, PMP_DECLUNAVAIL); + strcpy(decl->version, PMP_DECLUNAVAIL); + strcpy(decl->max_version, PMP_DECLUNAVAIL); + strcpy(decl->min_version, PMP_DECLUNAVAIL); - // Set enviroments. - 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 | PMPPEF_RECURSIVE; - ucs2cpy(pmpenv->path_to_playlist.path, pmpi->env.path_to_playlist); - ucs2cpy(pmpenv->playlist_ext, pmpi->env.playlist_ext); + info->music_flag = PMPMF_SUPPORT | PMPMF_RECURSIVE; + info->playlist_flag = PMPPF_SUPPORT; + // Audio codecs. + info->num_audio_codecs = sizeof(g_codecs) / sizeof(g_codecs[0]); + info->audio_codecs = (uint32_t*)ucs2malloc(sizeof(uint32_t) * info->num_audio_codecs); + memcpy(info->audio_codecs, g_codecs, sizeof(g_codecs)); + + // Obtain the number of extensions separated by '\0' characters. + info->num_audio_extensions = sizeof(g_music_exts) / sizeof(g_music_exts[0]); + info->audio_extensions = (ucs2char_t**)ucs2malloc(sizeof(ucs2char_t*) * info->num_audio_extensions); + for (i = 0;i < info->num_audio_extensions;++i) { + info->audio_extensions[i] = mbsdupucs2(g_music_exts[i]); + } + // 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; @@ -244,7 +263,9 @@ { uint32_t count = pmplib_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); } return count; @@ -253,192 +274,170 @@ static result_t pmp_open(pmp_t* pmp, uint32_t flag) { result_t ret = 0; + + // Set the open flag. pmp->flag = flag; - if (pmp->flag & PMPOF_MUSIC_DB_READ) { - ret = pmpdb_read(pmp->music); - if (ret != 0) { - return ret; - } + // Open the music database. + ret = pmpmusic_open(pmp->music); + if (ret) { + return ret; } + return 0; } -static result_t pmp_close(pmp_t* pmp, uint32_t flag) +static result_t pmp_close(pmp_t* pmp) { result_t ret = 0; - if (pmp->flag & PMPOF_MUSIC_DB_WRITE) { - ret = pmpdb_write(pmp->music); - if (ret != 0) { - return ret; - } - } - return 0; -} -static result_t pmp_create_instance_db(pmp_t* pmp, pmp_music_t** ptr_pmpdb) -{ - pmp_music_t* pmpdb = NULL; - irivnavi_t* irivnavi = NULL; - - *ptr_pmpdb = 0; - - // Allocate a PMPDB instance. - pmpdb = (pmp_music_t*)calloc(1, sizeof(pmp_music_t)); - if (!pmpdb) { - return PMPDBE_OUTOFMEMORY; + // Close the music database. + ret = pmpmusic_close(pmp->music); + if (ret) { + return ret; } - // Set member methods. - 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; - - // Allocate and initialize an internal object (irivnavi_t). - irivnavi = (irivnavi_t*)calloc(1, sizeof(irivnavi_t)); - if (!irivnavi) { - free(pmpdb); - return PMPDBE_OUTOFMEMORY; - } - irivnavi_init(irivnavi); - - // Set member variables. - pmpdb->pmp = pmp; - pmpdb->instance = irivnavi; - - *ptr_pmpdb = pmpdb; return 0; } -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) { + pmp_music_t* music = NULL; pmp_internal_t* pmpi = (pmp_internal_t*)pmp->instance; - pmp_playlist_t* pmppl = NULL; + pmp_music_internal_t* pmpmi = NULL; - *ptr_pmppl = 0; + *ptr_music = 0; - pmppl = (pmp_playlist_t*)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; + pmpmi = calloc(1, sizeof(pmp_music_internal_t)); + if (!pmpmi) { + free(music); + return PMPDBE_OUTOFMEMORY; + } + irivnavi_init(&pmpmi->db); - pmppl->pmp = pmp; + 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 = pmpmi; - pmppl->add_ref(pmppl); - *ptr_pmppl = pmppl; + *ptr_music = music; return 0; } -static uint32_t pmpdb_release(pmp_music_t* pmpdb) +static uint32_t pmpmusic_release(pmp_music_t* music) { - irivnavi_t* db = (irivnavi_t*)pmpdb->instance; - if (db) { - irivnavi_finish(db); - free(db); - } - free(pmpdb); + pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance; + irivnavi_finish(&pmpmi->db); + pmplib_records_finish(pmpmi->records, pmpmi->num_records); + free(pmpmi->playlists); + free(pmpmi); + free(music); return 0; } -result_t pmpdb_read(pmp_music_t* pmpdb) +uint32_t pmpmusic_open(pmp_music_t* music) { - irivnavi_t* db = (irivnavi_t*)pmpdb->instance; + pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance; result_t ret = 0; FILE *fp = NULL; ucs2char_t filename[MAX_PATH]; long size = 0; + int i, j; uint8_t *buffer = NULL; + static const ucs2char_t ucs2cs_mp3[] = {'.','m','p','3',0}; + static const ucs2char_t ucs2cs_ogg[] = {'.','o','g','g',0}; + static const ucs2char_t ucs2cs_wma[] = {'.','w','m','a',0}; + static const ucs2char_t ucs2cs_wav[] = {'.','w','a','v',0}; - // Open a database file in the root directory. - ucs2cpy(filename, pmpdb->pmp->env.path_to_root.path); - filepath_addslash(filename); - ucs2cat(filename, ucs2cs_irivnavi_idb); - fp = ucs2fopen(filename, "rb"); - if (!fp) { - return PMPDBE_OPENFORREAD; - } + if (music->pmp->flag & PMPOF_MUSIC_DB_READ) { + // Open a database file in the root directory. + ucs2cpy(filename, music->pmp->info.path_to_root); + filepath_addslash(filename); + ucs2cat(filename, ucs2cs_irivnavi_idb); + fp = ucs2fopen(filename, "rb"); + if (!fp) { + return PMPDBE_OPENFORREAD; + } - // Obtain the stream size. - if (fseek(fp, 0, SEEK_END) != 0) { - return PMPDBE_OPENFORREAD; - } - if ((size = ftell(fp)) == -1) { - return PMPDBE_OPENFORREAD; - } - if (fseek(fp, 0, SEEK_SET) != 0) { - return PMPDBE_OPENFORREAD; - } + // Obtain the stream size. + if (fseek(fp, 0, SEEK_END) != 0) { + return PMPDBE_OPENFORREAD; + } + if ((size = ftell(fp)) == -1) { + return PMPDBE_OPENFORREAD; + } + if (fseek(fp, 0, SEEK_SET) != 0) { + return PMPDBE_OPENFORREAD; + } - // Allocate a buffer that stores the whole data. - buffer = (uint8_t*)malloc(size); - if (!buffer) { - ret = PMPDBE_OUTOFMEMORY; - goto error_exit; - } + // Allocate a buffer that stores the whole data. + buffer = (uint8_t*)malloc(size); + if (!buffer) { + ret = PMPDBE_OUTOFMEMORY; + goto error_exit; + } - // Read at one time. - fread(buffer, 1, size, fp); + // Read at one time. + fread(buffer, 1, size, fp); - // Read the data from the buffer. - if (irivnavi_serialize(db, buffer, 0) == 0) { - ret = PMPDBE_DBINCONSIST; - goto error_exit; - } + // Read the data from the buffer. + if (irivnavi_serialize(&pmpmi->db, buffer, 0) == 0) { + ret = PMPDBE_DBINCONSIST; + goto error_exit; + } - free(buffer); - fclose(fp); - return 0; + // Free the buffer and file. + free(buffer); + fclose(fp); -error_exit: - free(buffer); - if (fp) fclose(fp); - return ret; -} + // + pmpmi->num_records = pmpmi->db.num_records; + pmpmi->records = (pmp_music_record_t*)ucs2malloc(sizeof(pmp_music_record_t) * pmpmi->num_records); -result_t pmpdb_write(pmp_music_t* pmpdb) -{ - irivnavi_t* db = (irivnavi_t*)pmpdb->instance; - result_t ret = 0; - FILE *fp = NULL; - ucs2char_t filename[MAX_PATH]; - uint8_t *buffer = NULL; + for (i = 0, j = 0;i < pmpmi->num_records;++i) { + size_t length = 0; + ucs2char_t* tmp = NULL; + const record_t* src = &pmpmi->db.records[i]; + pmp_music_record_t* dst = &pmpmi->records[j]; - // Open a database file in the root directory. - ucs2cpy(filename, pmpdb->pmp->env.path_to_root.path); - filepath_addslash(filename); - ucs2cat(filename, ucs2cs_irivnavi_idb); - filepath_removefile(filename); - fp = ucs2fopen(filename, "wb"); - if (!fp) { - return PMPDBE_OPENFORREAD; - } + pmplib_record_init(dst); - irivnavi_update(db); + tmp = mbsdupucs2(src->filename); + length = ucs2len(music->pmp->info.path_to_root); + length += ucs2len(tmp); + length += 3; - // Allocate a buffer that stores the whole data. - buffer = (uint8_t*)malloc(db->size); - if (!buffer) { - ret = PMPDBE_OUTOFMEMORY; - goto error_exit; - } + dst->filename = ucs2malloc(sizeof(ucs2char_t) * length); + filepath_combinepath(dst->filename, length, music->pmp->info.path_to_root, tmp); + dst->title = mbsdupucs2(src->title); + dst->artist = mbsdupucs2(src->artist); + dst->album = mbsdupucs2(src->album); + dst->genre = mbsdupucs2(src->genre); - // Write the data to the buffer. - if (irivnavi_serialize(db, buffer, 1) == 0) { - ret = PMPDBE_DBINCONSIST; - goto error_exit; - } + // Set codec information according to the file extensions. + if (filepath_hasext(dst->filename, ucs2cs_mp3)) { + dst->codec = PMPCODEC_MPEGLAYER3; + } else if (filepath_hasext(dst->filename, ucs2cs_ogg)) { + dst->codec = PMPCODEC_VORBIS; + } else if (filepath_hasext(dst->filename, ucs2cs_wma)) { + dst->codec = PMPCODEC_WMA; + } else if (filepath_hasext(dst->filename, ucs2cs_wav)) { + dst->codec = PMPCODEC_WAV; + } - // Write at one time. - fwrite(buffer, 1, db->size, fp); + dst->ts_update = src->timestamp; - free(buffer); - fclose(fp); + ucs2free(tmp); + ++j; + } + } return 0; error_exit: @@ -447,171 +446,169 @@ return ret; } -result_t pmpdb_set(pmp_music_t* pmpdb, const pmp_music_record_t* records, uint32_t num_records) +result_t pmpmusic_close(pmp_music_t* music) { - irivnavi_t* db = (irivnavi_t*)pmpdb->instance; + int i, j; + pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance; result_t ret = 0; - uint32_t i, j, n = 0; + FILE *fp = NULL; + ucs2char_t filename[MAX_PATH]; + uint8_t *buffer = NULL; static const ucs2char_t ucs2cs_unknown[] = {'u','n','k','n','o','w','n',0}; - const ucs2char_t* path_to_root = pmpdb->pmp->env.path_to_root.path; + static const ucs2char_t m3u_ext[] = {'.','m','3','u',0}; - // Clear the database. - irivnavi_finish(db); - irivnavi_init(db); + if (music->pmp->flag & PMPOF_MUSIC_DB_WRITE) { + // Clear the database. + irivnavi_finish(&pmpmi->db); + irivnavi_init(&pmpmi->db); - // Count the number of valid entries. - n = 0; - for (i = 0;i < num_records;++i) { - if (pmpdb_is_supported_codec(pmpdb, records[i].codec)) { - ++n; + // Initialize the record array. + if (irivnavi_init_records(&pmpmi->db, pmpmi->num_records) != 0) { + return PMPDBE_OUTOFMEMORY; } - } + + // Convert records from pmp_music_record_t to ip2db_record_t. + for (i = 0, j = 0;i < pmpmi->num_records;++i) { + const pmp_music_record_t* src = &pmpmi->records[i]; + record_t* dst = &pmpmi->db.records[j]; - // Initialize the record array. - if (irivnavi_init_records(db, n) != 0) { - return PMPDBE_OUTOFMEMORY; - } - - // Convert records from pmp_music_record_t to ip2db_record_t. - for (i = 0, j = 0;i < num_records;++i) { - const pmp_music_record_t* src = &records[i]; - record_t* dst = &db->records[j]; + // Set record fields. + record_init(dst); + dst->filename = ucs2dupmbs(filepath_skipdrive(src->filename, music->pmp->info.path_to_root)); + dst->title = src->title ? ucs2dupmbs(src->title) : ucs2dupmbs(filepath_skippath(src->filename));; + dst->artist = ucs2dupmbs(src->artist ? src->artist : ucs2cs_unknown); + dst->album = ucs2dupmbs(src->album ? src->album : ucs2cs_unknown); + dst->genre = ucs2dupmbs(src->genre ? src->genre : ucs2cs_unknown); + dst->timestamp = src->ts_update; - // Skip unsupported codec. - if (!pmpdb_is_supported_codec(pmpdb, src->codec)) { - continue; + ++j; } - // Set record fields. - record_init(dst); - dst->filename = ucs2dupmbs(filepath_skipdrive(src->filename, path_to_root)); - dst->title = src->title ? ucs2dupmbs(src->title) : ucs2dupmbs(filepath_skippath(src->filename));; - dst->artist = ucs2dupmbs(src->artist ? src->artist : ucs2cs_unknown); - dst->album = ucs2dupmbs(src->album ? src->album : ucs2cs_unknown); - dst->genre = ucs2dupmbs(src->genre ? src->genre : ucs2cs_unknown); - dst->timestamp = src->ts_update; + pmpmi->db.num_records = pmpmi->num_records; - ++j; - } + // Open a database file in the root directory. + ucs2cpy(filename, music->pmp->info.path_to_root); + filepath_addslash(filename); + ucs2cat(filename, ucs2cs_irivnavi_idb); + filepath_removefile(filename); + fp = ucs2fopen(filename, "wb"); + if (!fp) { + return PMPDBE_OPENFORREAD; + } - db->num_records = n; + irivnavi_update(&pmpmi->db); - return 0; -} + // Allocate a buffer that stores the whole data. + buffer = (uint8_t*)malloc(pmpmi->db.size); + if (!buffer) { + ret = PMPDBE_OUTOFMEMORY; + goto error_exit; + } -static result_t pmpdb_get(pmp_music_t* pmpdb, pmp_music_record_t* records, uint32_t* num_records) -{ - irivnavi_t* db = (irivnavi_t*)pmpdb->instance; - result_t ret = 0; - uint32_t i, j, n = db->num_records; - const ucs2char_t* path_to_root = pmpdb->pmp->env.path_to_root.path; - static const ucs2char_t ucs2cs_mp3[] = {'.','m','p','3',0}; - static const ucs2char_t ucs2cs_ogg[] = {'.','o','g','g',0}; - static const ucs2char_t ucs2cs_wma[] = {'.','w','m','a',0}; - static const ucs2char_t ucs2cs_wav[] = {'.','w','a','v',0}; + // Write the data to the buffer. + if (irivnavi_serialize(&pmpmi->db, buffer, 1) == 0) { + ret = PMPDBE_DBINCONSIST; + goto error_exit; + } - if (!records) { - *num_records = n; - return 0; - } + // Write at one time. + fwrite(buffer, 1, pmpmi->db.size, fp); - if (*num_records < n) { - *num_records = n; - return PMPDBE_INSUFFICIENT; + free(buffer); + fclose(fp); } - for (i = 0, j = 0;i < n;++i) { - size_t length = 0; - ucs2char_t* tmp = NULL; - const record_t* src = &db->records[i]; - pmp_music_record_t* dst = &records[j]; + if (music->pmp->flag & PMPOF_MUSIC_PL_WRITE) { + int i; - pmplib_record_init(dst); + for (i = 0;i < pmpmi->num_playlists;++i) { + const ucs2char_t* path_to_root = music->pmp->info.path_to_root; + const ucs2char_t* path_to_playlist = music->pmp->info.path_to_playlist; + const pmp_playlist_t* pl = &pmpmi->playlists[i]; + ucs2char_t dst[MAX_PATH]; - tmp = mbsdupucs2(src->filename); - length = ucs2len(path_to_root); - length += ucs2len(tmp); - length += 3; + filepath_combinepath(dst, MAX_PATH, path_to_root, path_to_playlist); + filepath_addslash(dst); + ucs2cat(dst, pl->name); + ucs2cat(dst, m3u_ext); - dst->filename = ucs2malloc(sizeof(ucs2char_t) * length); - filepath_combinepath(dst->filename, length, path_to_root, tmp); - dst->title = mbsdupucs2(src->title); - dst->artist = mbsdupucs2(src->artist); - dst->album = mbsdupucs2(src->album); - dst->genre = mbsdupucs2(src->genre); - // Set codec information according to the file extensions. - if (filepath_hasext(dst->filename, ucs2cs_mp3)) { - dst->codec = PMPCODEC_MPEGLAYER3; - } else if (filepath_hasext(dst->filename, ucs2cs_ogg)) { - dst->codec = PMPCODEC_VORBIS; - } else if (filepath_hasext(dst->filename, ucs2cs_wma)) { - dst->codec = PMPCODEC_WMA; - } else if (filepath_hasext(dst->filename, ucs2cs_wav)) { - dst->codec = PMPCODEC_WAV; + if (playlist_write( + dst, + pl->entries, + pl->num_entries, + path_to_root + ) != 0) { + return PMPPLE_WRITE; + } } - - dst->ts_update = src->timestamp; - - ucs2free(tmp); - ++j; } return 0; + +error_exit: + free(buffer); + if (fp) fclose(fp); + return ret; } +static result_t pmpmusic_set_records(pmp_music_t* music, const pmp_music_record_t* records, uint32_t num_records) +{ + pmp_t* pmp = music->pmp; + pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance; + /* Free records attached to pmpmi. */ + pmplib_records_finish(pmpmi->records, pmpmi->num_records); -result_t pmpdb_dump(pmp_music_t* pmpdb, FILE *fp, int level) -{ - irivnavi_t* db = (irivnavi_t*)pmpdb->instance; - irivnavi_repr(db, fp, level); + /* Allocate new records. */ + pmpmi->records = (pmp_music_record_t*)ucs2malloc(sizeof(pmp_music_record_t) * num_records); + pmpmi->num_records = num_records; + pmplib_records_clone(pmpmi->records, records, num_records); + return 0; -} + } -static int pmpdb_is_supported_codec(pmp_music_t* pmpdb, uint32_t codec) +static result_t pmpmusic_get_records(pmp_music_t* music, pmp_music_record_t* records, uint32_t* num_records) { - return ( - (codec == PMPCODEC_MPEGLAYER3) || - (codec == PMPCODEC_VORBIS) || - (codec == PMPCODEC_WMA) || - (codec == PMPCODEC_WAV) - ) ? 1 : 0; + pmp_t* pmp = music->pmp; + pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance; + + if (!records) { + *num_records = pmpmi->num_records; + return 0; + } else if (*num_records == pmpmi->num_records) { + pmplib_records_clone(records, pmpmi->records, pmpmi->num_records); + return 0; + } else { + return PMPDBE_INSUFFICIENT; + } } -static int pmpdb_is_supported_ext(pmp_music_t* pmpdb, const ucs2char_t* filename) +static result_t pmpmusic_dump(pmp_music_t* music, FILE *fp, int level) { - static const ucs2char_t ucs2cs_mp3[] = {'.','m','p','3',0}; - static const ucs2char_t ucs2cs_ogg[] = {'.','o','g','g',0}; - static const ucs2char_t ucs2cs_wma[] = {'.','w','m','a',0}; - static const ucs2char_t ucs2cs_wav[] = {'.','w','a','v',0}; - - return ( - filepath_hasext(filename, ucs2cs_mp3) || - filepath_hasext(filename, ucs2cs_ogg) || - filepath_hasext(filename, ucs2cs_wma) || - filepath_hasext(filename, ucs2cs_wav) - ) ? 1 : 0; + pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance; + irivnavi_repr(&pmpmi->db, fp, level); + return 0; } +static result_t pmpmusic_set_playlists(pmp_music_t* music, const pmp_playlist_t* playlists, uint32_t num_playlists) +{ + pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance; + // Free playlists attached to pmpmi. + pmplib_playlists_finish(pmpmi->playlists, pmpmi->num_playlists); + // Allocate a new playlists. + pmpmi->playlists = (pmp_playlist_t*)calloc(num_playlists, sizeof(pmp_playlist_t)); + pmpmi->num_playlists = num_playlists; + // Copy the playlist array. + pmplib_playlists_clone(pmpmi->playlists, playlists, num_playlists); -static uint32_t pmppl_add_ref(pmp_playlist_t* pmppl) -{ - return pmplib_interlocked_increment(&pmppl->ref_count); + return 0; } -static uint32_t pmppl_release(pmp_playlist_t* pmppl) -{ - uint32_t count = pmplib_interlocked_decrement(&pmppl->ref_count); - if (count == 0) { - 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) { pmp_internal_t* pmpi = (pmp_internal_t*)pmppl->pmp->instance; @@ -620,3 +617,4 @@ } return 0; } +*/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |