From: <ny...@us...> - 2006-12-24 15:38:22
|
Revision: 196 http://svn.sourceforge.net/pmplib/?rev=196&view=rev Author: nyaochi Date: 2006-12-24 07:38:22 -0800 (Sun, 24 Dec 2006) Log Message: ----------- Read and dump routines for db.dic Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.h trunk/pmplib/lib/pmp_iriverplus3/dic.c trunk/pmplib/lib/pmp_iriverplus3/dic.h trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-24 05:09:19 UTC (rev 195) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-24 15:38:22 UTC (rev 196) @@ -19,16 +19,16 @@ * */ -/* $Id:$ */ +/* $Id$ */ #ifndef __IP3DB_DAT_H__ #define __IP3DB_DAT_H__ typedef struct { - uint32_t uid; - uint32_t parent_uid; - uint8_t properties; - uint16_t filetype; + uint32_t uid; + uint32_t parent_uid; + uint8_t properties; + uint16_t filetype; ucs2char_t* object_name; ucs2char_t* name; uint32_t filesize; @@ -48,32 +48,32 @@ } dat_objects_t; typedef struct { - ucs2char_t* artist; - ucs2char_t* album; - ucs2char_t* genre; - ucs2char_t* title; - ucs2char_t* filepath; - ucs2char_t* filename; - uint32_t duration; - uint16_t rating; - uint32_t use_count; - uint16_t format; - uint16_t tracknumber; - uint8_t drm; - uint8_t lyric; - uint8_t purchase; - uint16_t protection; - uint32_t samplerate; - uint32_t bitrate; - uint8_t changed_flag; - uint32_t codec; - uint32_t clusm; - uint32_t clusa; - uint32_t albumart_pos; - ucs2char_t* release; - ucs2char_t* album_artist; - uint32_t object_uid; - uint32_t ratingtime; + ucs2char_t* artist; + ucs2char_t* album; + ucs2char_t* genre; + ucs2char_t* title; + ucs2char_t* filepath; + ucs2char_t* filename; + uint32_t duration; + uint16_t rating; + uint32_t use_count; + uint16_t format; + uint16_t tracknumber; + uint8_t drm; + uint8_t lyric; + uint8_t purchase; + uint16_t protection; + uint32_t samplerate; + uint32_t bitrate; + uint8_t changed_flag; + uint32_t codec; + uint32_t clusm; + uint32_t clusa; + uint32_t albumart_pos; + ucs2char_t* release; + ucs2char_t* album_artist; + uint32_t object_uid; + uint32_t ratingtime; } dat_music_t; typedef struct { Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-24 05:09:19 UTC (rev 195) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-24 15:38:22 UTC (rev 196) @@ -19,7 +19,7 @@ * */ -/* $Id:$ */ +/* $Id$ */ /* Some important findings from db.dic: @@ -38,17 +38,99 @@ #include <ucs2char.h> #include "serialize.h" +#include "util.h" #include "ip3db.h" +#include "dic.h" -/* -typedef struct { - uint32_t next; - uint32_t type; - uint32_t idx_root; - ucs2char_t* name; -} dic_entry_t; -*/ +dic_t* dic_new() +{ + dic_t* dic = (dic_t*)malloc(sizeof(dic_t)); + if (dic) { + memset(dic, 0, sizeof(*dic)); + dic->num_music_fields = IP3DBF_MUSIC_LAST; + dic->music_fields = (dic_entry_t*)calloc(dic->num_music_fields, sizeof(dic_entry_t)); + dic->num_objects_fields = IP3DBF_OBJECTS_LAST; + dic->objects_fields = (dic_entry_t*)calloc(dic->num_objects_fields, sizeof(dic_entry_t)); + } + return dic; +} +void dic_finish(dic_t* dic) +{ + if (dic) { + free(dic->music_fields); + free(dic->objects_fields); + free(dic); + } +} + +static size_t dic_serialize_field(uint8_t* block, dic_entry_t* entry, int is_storing) +{ + uint8_t *p = block; + p += serialize_uint32be(p, &entry->next, 0); + p += serialize_uint32be(p, &entry->type, 0); + p += serialize_uint32be(p, &entry->idx_root, 0); + if (is_storing) { + p += (serialize_ucs2be_string_var(p, entry->name, is_storing) + 1) * sizeof(ucs2char_t); + } else { + p += (serialize_ucs2be_string_var_alloc(p, &entry->name) + 1) * sizeof(ucs2char_t); + } + return (size_t)(p - block); +} + +int dic_serialize(dic_t* dic, uint8_t* buffer, int is_storing) +{ + int i; + uint32_t next = 0; + + next = 0x00000056; + for (i = 0;i < IP3DBF_MUSIC_LAST;++i) { + dic_serialize_field(buffer + next, &dic->music_fields[i], is_storing); + next = dic->music_fields[i].next; + } + + next = 0x0000099A; + for (i = 0;i < IP3DBF_OBJECTS_LAST;++i) { + dic_serialize_field(buffer + next, &dic->objects_fields[i], is_storing); + next = dic->objects_fields[i].next; + } + + return 0; +} + +void dic_dump(dic_t* dic, FILE *fp) +{ + int i; + + fprintf(fp, "===== db.dic =====\n"); + + fprintf(fp, "MUSIC {\n"); + for (i = 0;i < IP3DBF_MUSIC_LAST;++i) { + const dic_entry_t* entry = &dic->music_fields[i]; + fprintf(fp, " FIELD %d = {\n", i); + fprintf(fp, " next: 0x%08X\n", entry->next); + fprintf(fp, " type: 0x%08X\n", entry->type); + fprintf(fp, " idx_root: 0x%08X\n", entry->idx_root); + fprints(fp, " name: %s\n", entry->name); + fprintf(fp, " }\n"); + } + fprintf(fp, "}\n"); + + fprintf(fp, "OBJECTS {\n"); + for (i = 0;i < IP3DBF_OBJECTS_LAST;++i) { + const dic_entry_t* entry = &dic->objects_fields[i]; + fprintf(fp, " FIELD %d = {\n", i); + fprintf(fp, " next: 0x%08X\n", entry->next); + fprintf(fp, " type: 0x%08X\n", entry->type); + fprintf(fp, " idx_root: 0x%08X\n", entry->idx_root); + fprints(fp, " name: %s\n", entry->name); + fprintf(fp, " }\n"); + } + fprintf(fp, "}\n"); + + fprintf(fp, "\n"); +} + uint32_t dic_get_idxroot(uint8_t *buffer, int field) { uint32_t value; Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-24 05:09:19 UTC (rev 195) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-24 15:38:22 UTC (rev 196) @@ -19,11 +19,31 @@ * */ -/* $Id:$ */ +/* $Id$ */ #ifndef __IP3DB_DIC_H__ #define __IP3DB_DIC_H__ +typedef struct { + uint32_t next; + uint32_t type; + uint32_t idx_root; + ucs2char_t* name; +} dic_entry_t; + +struct tag_dic_t { + int num_music_fields; + dic_entry_t *music_fields; + int num_objects_fields; + dic_entry_t *objects_fields; +}; +typedef struct tag_dic_t dic_t; + +dic_t* dic_new(); +void dic_finish(dic_t* dic); +int dic_serialize(dic_t* dic, uint8_t* buffer, int is_storing); +void dic_dump(dic_t* dic, FILE *fp); + uint32_t dic_get_idxroot(uint8_t *buffer, int field); #endif/*__IP3DB_DIC_H__*/ Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-24 05:09:19 UTC (rev 195) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-24 15:38:22 UTC (rev 196) @@ -19,7 +19,7 @@ * */ -/* $Id:$ */ +/* $Id$ */ /* Brief summary of db.idx structure: @@ -61,16 +61,6 @@ uint32_t next; } tail_t; -typedef struct { - uint32_t type; - union { - uint8_t byte; - uint16_t word; - uint32_t dword; - ucs2char_t* str; - } value; -} variant_t; - static size_t idx_serialize_header(uint8_t *block, header_t *header, int is_storing) { uint8_t *p = block; @@ -98,13 +88,13 @@ return sizeof(tail_t); } -void variant_init(variant_t* var, int type) +void variant_init(ip3db_variant_t* var, int type) { memset(var, 0, sizeof(*var)); var->type = type; } -void variant_finish(variant_t* var) +void variant_finish(ip3db_variant_t* var) { if (var->type == IP3DBVT_STRING) { ucs2free(var->value.str); @@ -127,7 +117,7 @@ uint8_t* buffer, uint32_t offset, node_t* node, - variant_t* key, + ip3db_variant_t* key, int* types, int level, int flag, @@ -144,7 +134,7 @@ ) { node_t node; - variant_t key; + ip3db_variant_t key; int type = types[level]; uint8_t* p = buffer + offset; @@ -203,7 +193,7 @@ uint8_t* buffer, uint32_t offset, node_t* node, - variant_t* key, + ip3db_variant_t* key, int* types, int level, int flag, Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-24 05:09:19 UTC (rev 195) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-24 15:38:22 UTC (rev 196) @@ -31,8 +31,9 @@ #include <ucs2char.h> #include "util.h" +#include "ip3db.h" #include "dat.h" -#include "ip3db.h" +#include "dic.h" static ip3db_index_param_t ip3db_index_param[IP3DBIDX_LAST] = { {"Music.Title", 0x0086, {IP3DBVT_STRING, IP3DBVT_NONE, IP3DBVT_NONE}}, @@ -61,10 +62,14 @@ void ip3db_init(ip3db_t* db) { memset(db, 0, sizeof(*db)); + db->dat = dat_new(); + db->dic = dic_new(); } void ip3db_finish(ip3db_t* db) { + dic_finish(db->dic); + dat_finish(db->dat); free(db->dat_buffer); free(db->dic_buffer); free(db->idx_buffer); @@ -74,7 +79,6 @@ result_t ip3db_read(ip3db_t* db, const ucs2char_t* datfn, const ucs2char_t* dicfn, const ucs2char_t* idxfn) { FILE *fp = 0; - ucs2char_t filename[MAX_PATH]; fp = ucs2fopen(datfn, "rb"); if (!fp) { @@ -100,18 +104,28 @@ fread_all(fp, &db->idx_buffer, &db->idx_size); fclose(fp); + if (dic_serialize(db->dic, db->dic_buffer, 0) != 0) { + ip3db_finish(db); + return 1; + } + + if (dat_serialize(db->dat_buffer, db->dat, 0) != 0) { + ip3db_finish(db); + return 1; + } + return 0; } result_t ip3db_dump(ip3db_t* db, FILE *fpo) { + /* Dump db.dic */ + dic_dump(db->dic, fpo); + /* Dump db.dat */ - dat_t* dat = dat_new(); - dat_serialize(db->dat_buffer, dat, 0); - dat_dump(fpo, dat); - dat_finish(dat); + dat_dump(fpo, db->dat); /* Dump db.idx */ idx_dump(fpo, db); return 0; -} \ No newline at end of file +} Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-24 05:09:19 UTC (rev 195) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-24 15:38:22 UTC (rev 196) @@ -48,15 +48,79 @@ IP3DBIDX_MAX_KEYLEVEL = 3, }; +/** + * Field type IDs used in db.dic (Do not change the associated values) + */ enum { - IP3DBVT_NONE, - IP3DBVT_BYTE, - IP3DBVT_WORD, - IP3DBVT_DWORD, - IP3DBVT_STRING, + IP3DBVT_NONE = 0, + IP3DBVT_STRING = 1, + IP3DBVT_BYTE = 2, + IP3DBVT_WORD = 3, + IP3DBVT_DWORD = 4, }; +/** + * Variant type for field values. + */ +typedef struct { + uint32_t type; + union { + uint8_t byte; + uint16_t word; + uint32_t dword; + ucs2char_t* str; + } value; +} ip3db_variant_t; +enum { + IP3DBF_MUSIC_BEGIN = 0, + IP3DBF_MUSIC_ARTIST = 0, + IP3DBF_MUSIC_ALBUM, + IP3DBF_MUSIC_GENRE, + IP3DBF_MUSIC_TITLE, + IP3DBF_MUSIC_FILEPATH, + IP3DBF_MUSIC_FILENAME, + IP3DBF_MUSIC_DURATION, + IP3DBF_MUSIC_RATING, + IP3DBF_MUSIC_USECOUNT, + IP3DBF_MUSIC_FILEFORMAT, + IP3DBF_MUSIC_TRACKNUMBER, + IP3DBF_MUSIC_DRM, + IP3DBF_MUSIC_LYRIC, + IP3DBF_MUSIC_PURCHASE, + IP3DBF_MUSIC_PROTECTIONSTATUS, + IP3DBF_MUSIC_SAMPLERATE, + IP3DBF_MUSIC_BITRATE, + IP3DBF_MUSIC_CHANGEDFLAG, + IP3DBF_MUSIC_AUDIOWAVECODEC, + IP3DBF_MUSIC_CLUSM, + IP3DBF_MUSIC_CLUSA, + IP3DBF_MUSIC_ALBUMARTPOS, + IP3DBF_MUSIC_ORGRELEASEDATE, + IP3DBF_MUSIC_UID, + IP3DBF_MUSIC_RATINGTIME, + IP3DBF_MUSIC_LAST, +}; + +enum { + IP3DBF_OBJECTS_BEGIN = 0, + IP3DBF_OBJECTS_UID = 0, + IP3DBF_OBJECTS_PARENTUID, + IP3DBF_OBJECTS_PROPERTIES, + IP3DBF_OBJECTS_FILETYPE, + IP3DBF_OBJECTS_OBJECTNAME, + IP3DBF_OBJECTS_NAME, + IP3DBF_OBJECTS_FILESIZE, + IP3DBF_OBJECTS_DATECREA, + IP3DBF_OBJECTS_RAWID, + IP3DBF_OBJECTS_PUOID1, + IP3DBF_OBJECTS_PUOID2, + IP3DBF_OBJECTS_LAST, +}; + + + + typedef struct { const char* name; uint32_t dic_offset; @@ -64,6 +128,7 @@ } ip3db_index_param_t; struct tag_dat_t; typedef struct tag_dat_t dat_t; +struct tag_dic_t; typedef struct tag_dic_t dic_t; typedef struct { uint8_t* dat_buffer; @@ -74,6 +139,7 @@ long idx_size; dat_t* dat; + dic_t* dic; } ip3db_t; int idx_dump(FILE *fpo, ip3db_t* db); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-24 18:03:21
|
Revision: 197 http://svn.sourceforge.net/pmplib/?rev=197&view=rev Author: nyaochi Date: 2006-12-24 10:03:21 -0800 (Sun, 24 Dec 2006) Log Message: ----------- Generalized fields in db.dat by using field type definitions in db.dic Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/dat.h trunk/pmplib/lib/pmp_iriverplus3/dic.c trunk/pmplib/lib/pmp_iriverplus3/dic.h trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-24 15:38:22 UTC (rev 196) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-24 18:03:21 UTC (rev 197) @@ -19,7 +19,7 @@ * */ -/* $Id:$ */ +/* $Id$ */ /* Brief summary of db.dat structure: @@ -42,277 +42,179 @@ #include "serialize.h" #include "util.h" +#include "ip3db.h" +#include "dic.h" #include "dat.h" -static void dat_object_finish(dat_object_t* entry) +static void dat_entry_init(dat_entry_t* entry, const dic_list_t* dic_list) { - ucs2free(entry->object_name); - ucs2free(entry->name); + int i; + memset(entry, 0, sizeof(*entry)); + entry->num_fields = dic_list->num_fields; + entry->fields = (ip3db_variant_t*)malloc(sizeof(ip3db_variant_t) * entry->num_fields); + for (i = 0;i < entry->num_fields;++i) { + ip3db_variant_init(&entry->fields[i], dic_list->fields[i].type); + } } -static void dat_objects_init(dat_objects_t* objects) +static void dat_entry_finish(dat_entry_t* entry) { - memset(objects, 0, sizeof(dat_objects_t)); -} - -static void dat_objects_finish(dat_objects_t* objects) -{ - uint32_t i; - for (i = 0;i < objects->num_entries;++i) { - dat_object_finish(&objects->entries[i]); + int i; + for (i = 0;i < entry->num_fields;++i) { + ip3db_variant_finish(&entry->fields[i]); } - free(objects->entries); - free(objects->offsets); - dat_objects_init(objects); + free(entry->fields); + memset(entry, 0, sizeof(*entry)); } -static size_t dat_objects_serialize(uint8_t* buffer, dat_objects_t* objects, int is_storing) +static size_t dat_entry_serialize(uint8_t* block, uint8_t* q, dat_entry_t* entry, int is_storing) { - uint32_t i; - uint8_t *p = buffer; - uint8_t *q = buffer + 0x00020000 - sizeof(uint32_t); + int i; + uint8_t *p = block; - p += serialize_uint32be(p, &objects->size, is_storing); - p += serialize_uint32be(p, &objects->num_entries, is_storing); - p += serialize_uint32be(p, &objects->unknown1, is_storing); - p += serialize_uint32be(p, &objects->unknown2, is_storing); + q -= serialize_uint32be(q, &entry->offset, is_storing); - if (!is_storing) { - free(objects->entries); - free(objects->offsets); - objects->entries = (dat_object_t*)calloc(objects->num_entries, sizeof(dat_object_t)); - objects->offsets = (uint32_t*)calloc(objects->num_entries, sizeof(uint32_t)); - } - - for (i = 0;i < objects->num_entries;++i) { - dat_object_t* entry = &objects->entries[i]; - - /* Read an element in the offset table. */ - q -= serialize_uint32be(q, &objects->offsets[i], is_storing); - - /* Read an entry. */ - p += serialize_uint32be(p, &entry->uid, is_storing); - p += serialize_uint32be(p, &entry->parent_uid, is_storing); - p += serialize_uint8(p, &entry->properties, is_storing); - p += serialize_uint16be(p, &entry->filetype, is_storing); - if (is_storing) { - p += (serialize_ucs2be_string_var(p, entry->object_name, is_storing) + 1) * sizeof(ucs2char_t); - p += (serialize_ucs2be_string_var(p, entry->name, is_storing) + 1) * sizeof(ucs2char_t); - } else { - p += (serialize_ucs2be_string_var_alloc(p, &entry->object_name) + 1) * sizeof(ucs2char_t); - p += (serialize_ucs2be_string_var_alloc(p, &entry->name) + 1) * sizeof(ucs2char_t); + for (i = 0;i < entry->num_fields;++i) { + ip3db_variant_t* var = &entry->fields[i]; + switch (var->type) { + case IP3DBVT_STRING: + if (is_storing) { + p += (serialize_ucs2be_string_var(p, var->value.str, is_storing) + 1) * sizeof(ucs2char_t); + } else { + p += (serialize_ucs2be_string_var_alloc(p, &var->value.str) + 1) * sizeof(ucs2char_t); + } + break; + case IP3DBVT_BYTE: + p += serialize_uint8(p, &var->value.byte, is_storing); + break; + case IP3DBVT_WORD: + p += serialize_uint16be(p, &var->value.word, is_storing); + break; + case IP3DBVT_DWORD: + p += serialize_uint32be(p, &var->value.dword, is_storing); + break; } - p += serialize_uint32be(p, &entry->filesize, is_storing); - p += serialize_uint32be(p, &entry->datecrea, is_storing); - p += serialize_uint32be(p, &entry->rawid, is_storing); - p += serialize_uint32be(p, &entry->puoid1, is_storing); - p += serialize_uint32be(p, &entry->puoid2, is_storing); } - return (size_t)(p - buffer); + return (size_t)(p - block); } -static void dat_objects_dump(FILE *fp, dat_objects_t* objects) +static void dat_entry_dump(dat_entry_t* entry, FILE *fp, const dic_list_t* dic_list) { - uint32_t i; + int i; - fprintf(fp, "OBJECTS {\n"); - fprintf(fp, " size: 0x%08X\n", objects->size); - fprintf(fp, " num_entries: %d\n", objects->num_entries); - fprintf(fp, " unknown1: 0x%08X\n", objects->unknown1); - fprintf(fp, " unknown2: 0x%08X\n", objects->unknown2); + for (i = 0;i < entry->num_fields;++i) { + ip3db_variant_t* var = &entry->fields[i]; - for (i = 0;i < objects->num_entries;++i) { - dat_object_t* entry = &objects->entries[i]; - fprintf(fp, " ENTRY %d (0x%08X) = {\n", i, objects->offsets[i]); - fprintf(fp, " uid: %d\n", entry->uid); - fprintf(fp, " parent_uid: %d\n", entry->parent_uid); - fprintf(fp, " properties: 0x%02X\n", entry->properties); - fprintf(fp, " filetype: 0x%04X\n", entry->filetype); - fprints(fp, " object_name: %s\n", entry->object_name); - fprints(fp, " name: %s\n", entry->name); - fprintf(fp, " filesize: %d\n", entry->filesize); - fprintf(fp, " datecrea: %d\n", entry->datecrea); - fprintf(fp, " rawid: %d\n", entry->rawid); - fprintf(fp, " puoid1: %d\n", entry->puoid1); - fprintf(fp, " puoid2: %d\n", entry->puoid2); - fprintf(fp, " }\n"); + fprints(fp, " %s: ", dic_list->fields[i].name); + switch (var->type) { + case IP3DBVT_STRING: + fprints(fp, "%s\n", var->value.str); + break; + case IP3DBVT_BYTE: + fprintf(fp, "0x%02X\n", var->value.byte); + break; + case IP3DBVT_WORD: + fprintf(fp, "%d\n", var->value.word); + break; + case IP3DBVT_DWORD: + fprintf(fp, "%d\n", var->value.dword); + break; + } } - fprintf(fp, "}\n"); } - - -static void dat_music_finish(dat_music_t* entry) +static void dat_list_init(dat_list_t* list) { - ucs2free(entry->artist); - ucs2free(entry->album); - ucs2free(entry->genre); - ucs2free(entry->title); - ucs2free(entry->filepath); - ucs2free(entry->filename); - ucs2free(entry->release); - ucs2free(entry->album_artist); + memset(list, 0, sizeof(*list)); } -static void dat_musics_init(dat_musics_t* musics) +static void dat_list_finish(dat_list_t* list) { - memset(musics, 0, sizeof(dat_musics_t)); -} - -static void dat_musics_finish(dat_musics_t* musics) -{ uint32_t i; - for (i = 0;i < musics->num_entries;++i) { - dat_music_finish(&musics->entries[i]); + for (i = 0;i < list->num_entries;++i) { + dat_entry_finish(&list->entries[i]); } - free(musics->entries); - free(musics->offsets); - dat_musics_init(musics); + free(list->entries); + dat_list_init(list); } -static size_t dat_musics_serialize(uint8_t* buffer, dat_musics_t* musics, int is_storing) +static size_t dat_list_serialize(uint8_t* buffer, dat_list_t* list, int is_storing, const dic_list_t* dic_list) { uint32_t i; uint8_t *p = buffer; uint8_t *q = buffer + 0x00020000 - sizeof(uint32_t); - p += serialize_uint32be(p, &musics->size, is_storing); - p += serialize_uint32be(p, &musics->num_entries, is_storing); - p += serialize_uint32be(p, &musics->unknown1, is_storing); - p += serialize_uint32be(p, &musics->unknown2, is_storing); + p += serialize_uint32be(p, &list->size, is_storing); + p += serialize_uint32be(p, &list->num_entries, is_storing); + p += serialize_uint32be(p, &list->unknown1, is_storing); + p += serialize_uint32be(p, &list->unknown2, is_storing); if (!is_storing) { - free(musics->entries); - free(musics->offsets); - musics->entries = (dat_music_t*)calloc(musics->num_entries, sizeof(dat_music_t)); - musics->offsets = (uint32_t*)calloc(musics->num_entries, sizeof(uint32_t)); + free(list->entries); + list->entries = (dat_entry_t*)calloc(list->num_entries, sizeof(dat_entry_t)); + for (i = 0;i < list->num_entries;++i) { + dat_entry_init(&list->entries[i], dic_list); + } } - for (i = 0;i < musics->num_entries;++i) { - dat_music_t* entry = &musics->entries[i]; - - /* Read an element in the offset table. */ - q -= serialize_uint32be(q, &musics->offsets[i], is_storing); - - /* Read an entry. */ - if (is_storing) { - p += (serialize_ucs2be_string_var(p, entry->artist, is_storing) + 1) * sizeof(ucs2char_t); - p += (serialize_ucs2be_string_var(p, entry->album, is_storing) + 1) * sizeof(ucs2char_t); - p += (serialize_ucs2be_string_var(p, entry->genre, is_storing) + 1) * sizeof(ucs2char_t); - p += (serialize_ucs2be_string_var(p, entry->title, is_storing) + 1) * sizeof(ucs2char_t); - p += (serialize_ucs2be_string_var(p, entry->filepath, is_storing) + 1) * sizeof(ucs2char_t); - p += (serialize_ucs2be_string_var(p, entry->filename, is_storing) + 1) * sizeof(ucs2char_t); - } else { - p += (serialize_ucs2be_string_var_alloc(p, &entry->artist) + 1) * sizeof(ucs2char_t); - p += (serialize_ucs2be_string_var_alloc(p, &entry->album) + 1) * sizeof(ucs2char_t); - p += (serialize_ucs2be_string_var_alloc(p, &entry->genre) + 1) * sizeof(ucs2char_t); - p += (serialize_ucs2be_string_var_alloc(p, &entry->title) + 1) * sizeof(ucs2char_t); - p += (serialize_ucs2be_string_var_alloc(p, &entry->filepath) + 1) * sizeof(ucs2char_t); - p += (serialize_ucs2be_string_var_alloc(p, &entry->filename) + 1) * sizeof(ucs2char_t); - } - p += serialize_uint32be(p, &entry->duration, is_storing); - p += serialize_uint16be(p, &entry->rating, is_storing); - p += serialize_uint32be(p, &entry->use_count, is_storing); - p += serialize_uint16be(p, &entry->format, is_storing); - p += serialize_uint16be(p, &entry->tracknumber, is_storing); - p += serialize_uint8(p, &entry->drm, is_storing); - p += serialize_uint8(p, &entry->lyric, is_storing); - p += serialize_uint8(p, &entry->purchase, is_storing); - p += serialize_uint16be(p, &entry->protection, is_storing); - p += serialize_uint32be(p, &entry->samplerate, is_storing); - p += serialize_uint32be(p, &entry->bitrate, is_storing); - p += serialize_uint8(p, &entry->changed_flag, is_storing); - p += serialize_uint32be(p, &entry->codec, is_storing); - p += serialize_uint32be(p, &entry->clusm, is_storing); - p += serialize_uint32be(p, &entry->clusa, is_storing); - p += serialize_uint32be(p, &entry->albumart_pos, is_storing); - if (is_storing) { - p += (serialize_ucs2be_string_var(p, entry->release, is_storing) + 1) * sizeof(ucs2char_t); - p += (serialize_ucs2be_string_var(p, entry->album_artist, is_storing) + 1) * sizeof(ucs2char_t); - } else { - p += (serialize_ucs2be_string_var_alloc(p, &entry->release) + 1) * sizeof(ucs2char_t); - p += (serialize_ucs2be_string_var_alloc(p, &entry->album_artist) + 1) * sizeof(ucs2char_t); - } - p += serialize_uint32be(p, &entry->object_uid, is_storing); - p += serialize_uint32be(p, &entry->ratingtime, is_storing); + for (i = 0;i < list->num_entries;++i) { + dat_entry_t* entry = &list->entries[i]; + p += dat_entry_serialize(p, q, entry, is_storing); + q -= sizeof(uint32_t); } return (size_t)(p - buffer); } -static void dat_musics_dump(FILE *fp, dat_musics_t* musics) +static void dat_list_dump(dat_list_t* list, FILE *fp, const dic_list_t* dic_list) { uint32_t i; - fprintf(fp, "MUSICS {\n"); - fprintf(fp, " size: 0x%08X\n", musics->size); - fprintf(fp, " num_entries: %d\n", musics->num_entries); - fprintf(fp, " unknown1: 0x%08X\n", musics->unknown1); - fprintf(fp, " unknown2: 0x%08X\n", musics->unknown2); + fprintf(fp, " size: 0x%08X\n", list->size); + fprintf(fp, " num_entries: %d\n", list->num_entries); + fprintf(fp, " unknown1: 0x%08X\n", list->unknown1); + fprintf(fp, " unknown2: 0x%08X\n", list->unknown2); - for (i = 0;i < musics->num_entries;++i) { - dat_music_t* entry = &musics->entries[i]; - - fprintf(fp, " ENTRY %d (0x%08X) = {\n", i, musics->offsets[i]); - fprints(fp, " artist: %s\n", entry->artist); - fprints(fp, " album: %s\n", entry->album); - fprints(fp, " genre: %s\n", entry->genre); - fprints(fp, " title: %s\n", entry->title); - fprints(fp, " filepath: %s\n", entry->filepath); - fprints(fp, " filename: %s\n", entry->filename); - fprintf(fp, " duration: %d\n", entry->duration); - fprintf(fp, " rating: %d\n", entry->rating); - fprintf(fp, " use_count: %d\n", entry->use_count); - fprintf(fp, " format: 0x%04X\n", entry->format); - fprintf(fp, " tracknumber: %d\n", entry->tracknumber); - fprintf(fp, " drm: 0x%02X\n", entry->drm); - fprintf(fp, " lyric: 0x%02X\n", entry->lyric); - fprintf(fp, " purchase: 0x%02X\n", entry->purchase); - fprintf(fp, " protection: 0x%04X\n", entry->protection); - fprintf(fp, " samplerate: %d\n", entry->samplerate); - fprintf(fp, " bitrate: %d\n", entry->bitrate); - fprintf(fp, " changed_flag: 0x%02X\n", entry->changed_flag); - fprintf(fp, " codec: 0x%08X\n", entry->codec); - fprintf(fp, " clusm: 0x%08X\n", entry->clusm); - fprintf(fp, " clusa: 0x%08X\n", entry->clusa); - fprintf(fp, " albumart_pos: 0x%08X\n", entry->albumart_pos); - fprints(fp, " release: %s\n", entry->release); - fprints(fp, " album_artist: %s\n", entry->album_artist); - fprintf(fp, " object_uid: %d\n", entry->object_uid); - fprintf(fp, " ratingtime: %d\n", entry->ratingtime); + for (i = 0;i < list->num_entries;++i) { + dat_entry_t* entry = &list->entries[i]; + fprintf(fp, " ENTRY %d (0x%08X) = {\n", i, entry->offset); + dat_entry_dump(entry, fp, dic_list); fprintf(fp, " }\n"); } - fprintf(fp, "}\n"); } dat_t* dat_new() { dat_t* dat = (dat_t*)malloc(sizeof(dat_t)); if (dat) { - dat_objects_init(&dat->objects); - dat_musics_init(&dat->musics); + dat_list_init(&dat->objects); + dat_list_init(&dat->musics); } return dat; } void dat_finish(dat_t* dat) { - dat_objects_finish(&dat->objects); - dat_musics_finish(&dat->musics); + dat_list_finish(&dat->objects); + dat_list_finish(&dat->musics); free(dat); } -size_t dat_serialize(uint8_t* buffer, dat_t* dat, int is_storing) +size_t dat_serialize(dat_t* dat, const dic_t* dic, uint8_t* buffer, int is_storing) { - dat_objects_serialize(buffer, &dat->objects, is_storing); - dat_musics_serialize(buffer + 0x00020000, &dat->musics, is_storing); + dat_list_serialize(buffer, &dat->objects, is_storing, &dic->objects); + dat_list_serialize(buffer + 0x00020000, &dat->musics, is_storing, &dic->music); return 0; } -void dat_dump(FILE *fp, dat_t* dat) +void dat_dump(dat_t* dat, const dic_t* dic, FILE *fp) { fprintf(fp, "===== db.dat =====\n"); - dat_objects_dump(fp, &dat->objects); - dat_musics_dump(fp, &dat->musics); + fprintf(fp, "OBJECTS = {\n"); + dat_list_dump(&dat->objects, fp, &dic->objects); + fprintf(fp, "}\n"); + fprintf(fp, "MUSIC = {\n"); + dat_list_dump(&dat->musics, fp, &dic->music); + fprintf(fp, "}\n"); } Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-24 15:38:22 UTC (rev 196) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-24 18:03:21 UTC (rev 197) @@ -25,75 +25,28 @@ #define __IP3DB_DAT_H__ typedef struct { - uint32_t uid; - uint32_t parent_uid; - uint8_t properties; - uint16_t filetype; - ucs2char_t* object_name; - ucs2char_t* name; - uint32_t filesize; - uint32_t datecrea; - uint32_t rawid; - uint32_t puoid1; - uint32_t puoid2; -} dat_object_t; + int num_fields; + ip3db_variant_t *fields; + uint32_t offset; +} dat_entry_t; typedef struct { uint32_t size; uint32_t num_entries; uint32_t unknown1; uint32_t unknown2; - dat_object_t* entries; - uint32_t* offsets; -} dat_objects_t; + dat_entry_t* entries; +} dat_list_t; -typedef struct { - ucs2char_t* artist; - ucs2char_t* album; - ucs2char_t* genre; - ucs2char_t* title; - ucs2char_t* filepath; - ucs2char_t* filename; - uint32_t duration; - uint16_t rating; - uint32_t use_count; - uint16_t format; - uint16_t tracknumber; - uint8_t drm; - uint8_t lyric; - uint8_t purchase; - uint16_t protection; - uint32_t samplerate; - uint32_t bitrate; - uint8_t changed_flag; - uint32_t codec; - uint32_t clusm; - uint32_t clusa; - uint32_t albumart_pos; - ucs2char_t* release; - ucs2char_t* album_artist; - uint32_t object_uid; - uint32_t ratingtime; -} dat_music_t; - -typedef struct { - uint32_t size; - uint32_t num_entries; - uint32_t unknown1; - uint32_t unknown2; - dat_music_t* entries; - uint32_t* offsets; -} dat_musics_t; - struct tag_dat_t { - dat_objects_t objects; - dat_musics_t musics; + dat_list_t objects; + dat_list_t musics; }; typedef struct tag_dat_t dat_t; dat_t* dat_new(); void dat_finish(dat_t* dat); -size_t dat_serialize(uint8_t* buffer, dat_t* dat, int is_storing); -void dat_dump(FILE *fp, dat_t* dat); +size_t dat_serialize(dat_t* dat, const dic_t* dic, uint8_t* buffer, int is_storing); +void dat_dump(dat_t* dat, const dic_t* dic, FILE *fp); #endif/*__IP3DB_DAT_H__*/ Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-24 15:38:22 UTC (rev 196) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-24 18:03:21 UTC (rev 197) @@ -42,15 +42,60 @@ #include "ip3db.h" #include "dic.h" +static void dic_entry_init(dic_entry_t* entry) +{ + memset(entry, 0, sizeof(*entry)); +} + +static void dic_entry_finish(dic_entry_t* entry) +{ + ucs2free(entry->name); + dic_entry_init(entry); +} + +static void dic_entry_dump(const dic_entry_t* entry, FILE *fp) +{ + fprintf(fp, " next: 0x%08X\n", entry->next); + fprintf(fp, " type: 0x%08X\n", entry->type); + fprintf(fp, " idx_root: 0x%08X\n", entry->idx_root); + fprints(fp, " name: %s\n", entry->name); +} + +static void dic_list_init(dic_list_t* list) +{ + memset(list, 0, sizeof(*list)); +} + +static void dic_list_finish(dic_list_t* list) +{ + int i; + for (i = 0;i < list->num_fields;++i) { + dic_entry_finish(&list->fields[i]); + } + free(list->fields); +} + +static void dic_list_dump(dic_list_t* list, FILE *fp) +{ + int i; + for (i = 0;i < list->num_fields;++i) { + const dic_entry_t* entry = &list->fields[i]; + fprintf(fp, " FIELD %d = {\n", i); + dic_entry_dump(entry, fp); + fprintf(fp, " }\n"); + } +} + dic_t* dic_new() { dic_t* dic = (dic_t*)malloc(sizeof(dic_t)); if (dic) { - memset(dic, 0, sizeof(*dic)); - dic->num_music_fields = IP3DBF_MUSIC_LAST; - dic->music_fields = (dic_entry_t*)calloc(dic->num_music_fields, sizeof(dic_entry_t)); - dic->num_objects_fields = IP3DBF_OBJECTS_LAST; - dic->objects_fields = (dic_entry_t*)calloc(dic->num_objects_fields, sizeof(dic_entry_t)); + dic_list_init(&dic->music); + dic->music.num_fields = IP3DBF_MUSIC_LAST; + dic->music.fields = (dic_entry_t*)calloc(dic->music.num_fields, sizeof(dic_entry_t)); + dic_list_init(&dic->objects); + dic->objects.num_fields = IP3DBF_OBJECTS_LAST; + dic->objects.fields = (dic_entry_t*)calloc(dic->objects.num_fields, sizeof(dic_entry_t)); } return dic; } @@ -58,13 +103,13 @@ void dic_finish(dic_t* dic) { if (dic) { - free(dic->music_fields); - free(dic->objects_fields); + dic_list_finish(&dic->music); + dic_list_finish(&dic->objects); free(dic); } } -static size_t dic_serialize_field(uint8_t* block, dic_entry_t* entry, int is_storing) +static size_t dic_serialize_entry(uint8_t* block, dic_entry_t* entry, int is_storing) { uint8_t *p = block; p += serialize_uint32be(p, &entry->next, 0); @@ -83,16 +128,16 @@ int i; uint32_t next = 0; - next = 0x00000056; - for (i = 0;i < IP3DBF_MUSIC_LAST;++i) { - dic_serialize_field(buffer + next, &dic->music_fields[i], is_storing); - next = dic->music_fields[i].next; + next = 0x0000003C; + for (i = 0;i < dic->music.num_fields;++i) { + dic_serialize_entry(buffer + next, &dic->music.fields[i], is_storing); + next = dic->music.fields[i].next; } next = 0x0000099A; - for (i = 0;i < IP3DBF_OBJECTS_LAST;++i) { - dic_serialize_field(buffer + next, &dic->objects_fields[i], is_storing); - next = dic->objects_fields[i].next; + for (i = 0;i < dic->objects.num_fields;++i) { + dic_serialize_entry(buffer + next, &dic->objects.fields[i], is_storing); + next = dic->objects.fields[i].next; } return 0; @@ -100,34 +145,11 @@ void dic_dump(dic_t* dic, FILE *fp) { - int i; - fprintf(fp, "===== db.dic =====\n"); - fprintf(fp, "MUSIC {\n"); - for (i = 0;i < IP3DBF_MUSIC_LAST;++i) { - const dic_entry_t* entry = &dic->music_fields[i]; - fprintf(fp, " FIELD %d = {\n", i); - fprintf(fp, " next: 0x%08X\n", entry->next); - fprintf(fp, " type: 0x%08X\n", entry->type); - fprintf(fp, " idx_root: 0x%08X\n", entry->idx_root); - fprints(fp, " name: %s\n", entry->name); - fprintf(fp, " }\n"); - } - fprintf(fp, "}\n"); - + dic_list_dump(&dic->music, fp); fprintf(fp, "OBJECTS {\n"); - for (i = 0;i < IP3DBF_OBJECTS_LAST;++i) { - const dic_entry_t* entry = &dic->objects_fields[i]; - fprintf(fp, " FIELD %d = {\n", i); - fprintf(fp, " next: 0x%08X\n", entry->next); - fprintf(fp, " type: 0x%08X\n", entry->type); - fprintf(fp, " idx_root: 0x%08X\n", entry->idx_root); - fprints(fp, " name: %s\n", entry->name); - fprintf(fp, " }\n"); - } - fprintf(fp, "}\n"); - + dic_list_dump(&dic->objects, fp); fprintf(fp, "\n"); } Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-24 15:38:22 UTC (rev 196) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-24 18:03:21 UTC (rev 197) @@ -31,11 +31,14 @@ ucs2char_t* name; } dic_entry_t; +typedef struct { + int num_fields; + dic_entry_t *fields; +} dic_list_t; + struct tag_dic_t { - int num_music_fields; - dic_entry_t *music_fields; - int num_objects_fields; - dic_entry_t *objects_fields; + dic_list_t music; + dic_list_t objects; }; typedef struct tag_dic_t dic_t; Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-24 15:38:22 UTC (rev 196) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-24 18:03:21 UTC (rev 197) @@ -88,20 +88,6 @@ return sizeof(tail_t); } -void variant_init(ip3db_variant_t* var, int type) -{ - memset(var, 0, sizeof(*var)); - var->type = type; -} - -void variant_finish(ip3db_variant_t* var) -{ - if (var->type == IP3DBVT_STRING) { - ucs2free(var->value.str); - } - variant_init(var, IP3DBVT_NONE); -} - /** * Prototype definition of a callback function for idx_walk. * @param buffer The pointer to the index buffer. @@ -147,7 +133,7 @@ } /* Read the key value. */ - variant_init(&key, type); + ip3db_variant_init(&key, type); switch (type) { case IP3DBVT_BYTE: p += serialize_uint8(p, &key.value.byte, 0); Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-24 15:38:22 UTC (rev 196) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-24 18:03:21 UTC (rev 197) @@ -32,8 +32,8 @@ #include "util.h" #include "ip3db.h" +#include "dic.h" #include "dat.h" -#include "dic.h" static ip3db_index_param_t ip3db_index_param[IP3DBIDX_LAST] = { {"Music.Title", 0x0086, {IP3DBVT_STRING, IP3DBVT_NONE, IP3DBVT_NONE}}, @@ -54,6 +54,20 @@ {"Object.FileType-ParentUid-Properties", 0x0ACE, {IP3DBVT_WORD, IP3DBVT_DWORD, IP3DBVT_BYTE}}, }; +void ip3db_variant_init(ip3db_variant_t* var, int type) +{ + memset(var, 0, sizeof(*var)); + var->type = type; +} + +void ip3db_variant_finish(ip3db_variant_t* var) +{ + if (var->type == IP3DBVT_STRING) { + ucs2free(var->value.str); + } + ip3db_variant_init(var, IP3DBVT_NONE); +} + ip3db_index_param_t* ip3db_get_indexparam(int field) { return &ip3db_index_param[field]; @@ -109,7 +123,7 @@ return 1; } - if (dat_serialize(db->dat_buffer, db->dat, 0) != 0) { + if (dat_serialize(db->dat, db->dic, db->dat_buffer, 0) != 0) { ip3db_finish(db); return 1; } @@ -123,7 +137,7 @@ dic_dump(db->dic, fpo); /* Dump db.dat */ - dat_dump(fpo, db->dat); + dat_dump(db->dat, db->dic, fpo); /* Dump db.idx */ idx_dump(fpo, db); Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-24 15:38:22 UTC (rev 196) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-24 18:03:21 UTC (rev 197) @@ -97,6 +97,7 @@ IP3DBF_MUSIC_CLUSA, IP3DBF_MUSIC_ALBUMARTPOS, IP3DBF_MUSIC_ORGRELEASEDATE, + IP3DBF_MUSIC_ALBUMARTIST, IP3DBF_MUSIC_UID, IP3DBF_MUSIC_RATINGTIME, IP3DBF_MUSIC_LAST, @@ -146,6 +147,9 @@ ip3db_index_param_t* ip3db_get_indexparam(int field); +void ip3db_variant_init(ip3db_variant_t* var, int type); +void ip3db_variant_finish(ip3db_variant_t* var); + void ip3db_init(ip3db_t* db); void ip3db_finish(ip3db_t* db); result_t ip3db_read(ip3db_t* db, const ucs2char_t* datfn, const ucs2char_t* dicfn, const ucs2char_t* idxfn); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-25 07:46:59
|
Revision: 199 http://svn.sourceforge.net/pmplib/?rev=199&view=rev Author: nyaochi Date: 2006-12-24 23:46:57 -0800 (Sun, 24 Dec 2006) Log Message: ----------- Improve idx.c to use dic.c Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/dic.c trunk/pmplib/lib/pmp_iriverplus3/dic.h trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/idx.h trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-24 18:21:20 UTC (rev 198) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-25 07:46:57 UTC (rev 199) @@ -46,7 +46,7 @@ #include "dic.h" #include "dat.h" -static void dat_entry_init(dat_entry_t* entry, const dic_list_t* dic_list) +static void dat_entry_init(dat_entry_t* entry, const dic_table_t* dic_list) { memset(entry, 0, sizeof(*entry)); entry->fields = (ip3db_variant_t*)malloc(sizeof(ip3db_variant_t) * dic_list->num_fields); @@ -103,14 +103,18 @@ return (size_t)(p - block); } -static void dat_entry_dump(dat_entry_t* entry, const dic_list_t* dic_list, FILE *fp) +static void dat_entry_dump(dat_entry_t* entry, const dic_table_t* dic_list, FILE *fp) { int i; + /* Loop for all fields in this entry. */ for (i = 0;i < entry->num_fields;++i) { ip3db_variant_t* var = &entry->fields[i]; + /* Output the field name. */ fprints(fp, " %s: ", dic_list->fields[i].name); + + /* Output its value. */ switch (var->type) { case IP3DBVT_STRING: fprints(fp, "%s\n", var->value.str); @@ -128,6 +132,8 @@ } } + + static void dat_list_init(dat_list_t* list) { memset(list, 0, sizeof(*list)); @@ -143,7 +149,7 @@ dat_list_init(list); } -static size_t dat_list_serialize(dat_list_t* list, const dic_list_t* dic_list, uint8_t* buffer, int is_storing) +static size_t dat_list_serialize(dat_list_t* list, const dic_table_t* dic_list, uint8_t* buffer, int is_storing) { uint32_t i; uint8_t *p = buffer; @@ -171,7 +177,7 @@ return (size_t)(p - buffer); } -static void dat_list_dump(dat_list_t* list, const dic_list_t* dic_list, FILE *fp) +static void dat_list_dump(dat_list_t* list, const dic_table_t* dic_list, FILE *fp) { uint32_t i; @@ -188,6 +194,8 @@ } } + + dat_t* dat_new() { dat_t* dat = (dat_t*)malloc(sizeof(dat_t)); Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-24 18:21:20 UTC (rev 198) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-25 07:46:57 UTC (rev 199) @@ -42,60 +42,104 @@ #include "ip3db.h" #include "dic.h" -static void dic_entry_init(dic_entry_t* entry) +static dic_index_t music_indices[] = { + {0, 0x0086, {IP3DBF_MUSIC_TITLE, IP3DBF_MUSIC_NONE, IP3DBF_MUSIC_NONE}}, + {0, 0x00F8, {IP3DBF_MUSIC_RATING, IP3DBF_MUSIC_NONE, IP3DBF_MUSIC_NONE}}, + {0, 0x0152, {IP3DBF_MUSIC_TRACKNUMBER, IP3DBF_MUSIC_NONE, IP3DBF_MUSIC_NONE}}, + {0, 0x022C, {IP3DBF_MUSIC_CHANGEDFLAG, IP3DBF_MUSIC_NONE, IP3DBF_MUSIC_NONE}}, + {0, 0x027A, {IP3DBF_MUSIC_CLUSM, IP3DBF_MUSIC_NONE, IP3DBF_MUSIC_NONE}}, + {0, 0x031C, {IP3DBF_MUSIC_UID, IP3DBF_MUSIC_NONE, IP3DBF_MUSIC_NONE}}, + {0, 0x0352, {IP3DBF_MUSIC_GENRE, IP3DBF_MUSIC_ARTIST, IP3DBF_MUSIC_TITLE}}, + {0, 0x0384, {IP3DBF_MUSIC_ARTIST, IP3DBF_MUSIC_ALBUM, IP3DBF_MUSIC_TRACKNUMBER}}, + {0, 0x03C2, {IP3DBF_MUSIC_ARTIST, IP3DBF_MUSIC_TRACKNUMBER, IP3DBF_MUSIC_NONE}}, + {0, 0x03F4, {IP3DBF_MUSIC_ARTIST, IP3DBF_MUSIC_TITLE, IP3DBF_MUSIC_NONE}}, + {0, 0x041A, {IP3DBF_MUSIC_GENRE, IP3DBF_MUSIC_TITLE, IP3DBF_MUSIC_NONE}}, + {0, 0x043E, {IP3DBF_MUSIC_ALBUM, IP3DBF_MUSIC_TRACKNUMBER, IP3DBF_MUSIC_NONE}}, +}; + +static dic_index_t objects_indices[] = { + {0, 0x099A, {IP3DBF_OBJECTS_UID, IP3DBF_MUSIC_NONE, IP3DBF_MUSIC_NONE}}, + {0, 0x09F0, {IP3DBF_OBJECTS_FILETYPE, IP3DBF_MUSIC_NONE, IP3DBF_MUSIC_NONE}}, + {0, 0x0A0E, {IP3DBF_OBJECTS_OBJECTNAME, IP3DBF_MUSIC_NONE, IP3DBF_MUSIC_NONE}}, + {0, 0x0ACE, {IP3DBF_OBJECTS_FILETYPE, IP3DBF_OBJECTS_PARENTUID, IP3DBF_OBJECTS_PROPERTIES}}, +}; + +static void dic_field_init(dic_field_t* entry) { memset(entry, 0, sizeof(*entry)); } -static void dic_entry_finish(dic_entry_t* entry) +static void dic_field_finish(dic_field_t* entry) { ucs2free(entry->name); - dic_entry_init(entry); + dic_field_init(entry); } -static void dic_entry_dump(const dic_entry_t* entry, FILE *fp) +static size_t dic_field_serialize(uint8_t* block, dic_field_t* entry, int is_storing) { + uint8_t *p = block; + p += serialize_uint32be(p, &entry->next, 0); + p += serialize_uint32be(p, &entry->type, 0); + p += serialize_uint32be(p, &entry->idx_root, 0); + if (is_storing) { + p += (serialize_ucs2be_string_var(p, entry->name, is_storing) + 1) * sizeof(ucs2char_t); + } else { + p += (serialize_ucs2be_string_var_alloc(p, &entry->name) + 1) * sizeof(ucs2char_t); + } + return (size_t)(p - block); +} + +static void dic_field_dump(const dic_field_t* entry, FILE *fp) +{ fprintf(fp, " next: 0x%08X\n", entry->next); fprintf(fp, " type: 0x%08X\n", entry->type); fprintf(fp, " idx_root: 0x%08X\n", entry->idx_root); fprints(fp, " name: %s\n", entry->name); } -static void dic_list_init(dic_list_t* list) + + +static void dic_table_init(dic_table_t* list) { memset(list, 0, sizeof(*list)); } -static void dic_list_finish(dic_list_t* list) +static void dic_table_finish(dic_table_t* list) { int i; for (i = 0;i < list->num_fields;++i) { - dic_entry_finish(&list->fields[i]); + dic_field_finish(&list->fields[i]); } free(list->fields); } -static void dic_list_dump(dic_list_t* list, FILE *fp) +static void dic_table_dump(dic_table_t* list, FILE *fp) { int i; for (i = 0;i < list->num_fields;++i) { - const dic_entry_t* entry = &list->fields[i]; + const dic_field_t* entry = &list->fields[i]; fprintf(fp, " FIELD %d = {\n", i); - dic_entry_dump(entry, fp); + dic_field_dump(entry, fp); fprintf(fp, " }\n"); } } + + dic_t* dic_new() { dic_t* dic = (dic_t*)malloc(sizeof(dic_t)); if (dic) { - dic_list_init(&dic->music); + dic_table_init(&dic->music); dic->music.num_fields = IP3DBF_MUSIC_LAST; - dic->music.fields = (dic_entry_t*)calloc(dic->music.num_fields, sizeof(dic_entry_t)); - dic_list_init(&dic->objects); + dic->music.fields = (dic_field_t*)calloc(dic->music.num_fields, sizeof(dic_field_t)); + dic->music.num_indices = sizeof(music_indices) / sizeof(music_indices[0]); + dic->music.indices = music_indices; + dic_table_init(&dic->objects); dic->objects.num_fields = IP3DBF_OBJECTS_LAST; - dic->objects.fields = (dic_entry_t*)calloc(dic->objects.num_fields, sizeof(dic_entry_t)); + dic->objects.fields = (dic_field_t*)calloc(dic->objects.num_fields, sizeof(dic_field_t)); + dic->objects.num_indices = sizeof(objects_indices) / sizeof(objects_indices[0]); + dic->objects.indices = objects_indices; } return dic; } @@ -103,26 +147,12 @@ void dic_finish(dic_t* dic) { if (dic) { - dic_list_finish(&dic->music); - dic_list_finish(&dic->objects); + dic_table_finish(&dic->music); + dic_table_finish(&dic->objects); free(dic); } } -static size_t dic_serialize_entry(uint8_t* block, dic_entry_t* entry, int is_storing) -{ - uint8_t *p = block; - p += serialize_uint32be(p, &entry->next, 0); - p += serialize_uint32be(p, &entry->type, 0); - p += serialize_uint32be(p, &entry->idx_root, 0); - if (is_storing) { - p += (serialize_ucs2be_string_var(p, entry->name, is_storing) + 1) * sizeof(ucs2char_t); - } else { - p += (serialize_ucs2be_string_var_alloc(p, &entry->name) + 1) * sizeof(ucs2char_t); - } - return (size_t)(p - block); -} - int dic_serialize(dic_t* dic, uint8_t* buffer, int is_storing) { int i; @@ -130,16 +160,26 @@ next = 0x0000003C; for (i = 0;i < dic->music.num_fields;++i) { - dic_serialize_entry(buffer + next, &dic->music.fields[i], is_storing); + dic_field_serialize(buffer + next, &dic->music.fields[i], is_storing); next = dic->music.fields[i].next; } next = 0x0000099A; for (i = 0;i < dic->objects.num_fields;++i) { - dic_serialize_entry(buffer + next, &dic->objects.fields[i], is_storing); + dic_field_serialize(buffer + next, &dic->objects.fields[i], is_storing); next = dic->objects.fields[i].next; } + for (i = 0;i < dic->music.num_indices;++i) { + uint32_t offset = dic->music.indices[i].offset + sizeof(uint32_t) * 2; + serialize_uint32be(buffer + offset, &dic->music.indices[i].idx_root, is_storing); + } + + for (i = 0;i < dic->objects.num_indices;++i) { + uint32_t offset = dic->objects.indices[i].offset + sizeof(uint32_t) * 2; + serialize_uint32be(buffer + offset, &dic->objects.indices[i].idx_root, is_storing); + } + return 0; } @@ -147,17 +187,54 @@ { fprintf(fp, "===== db.dic =====\n"); fprintf(fp, "MUSIC {\n"); - dic_list_dump(&dic->music, fp); + dic_table_dump(&dic->music, fp); fprintf(fp, "OBJECTS {\n"); - dic_list_dump(&dic->objects, fp); + dic_table_dump(&dic->objects, fp); fprintf(fp, "\n"); } -uint32_t dic_get_idxroot(uint8_t *buffer, int field) +uint32_t dic_get_idxroot(dic_t* dic, int table, int index) { - uint32_t value; - ip3db_index_param_t* index_param = ip3db_get_indexparam(field); - uint8_t *p = buffer + index_param->dic_offset; - serialize_uint32be(p + sizeof(uint32_t) * 2, &value, 0); - return value; + const dic_index_t* indices = NULL; + switch (table) { + case IP3DBIDX_MUSIC: + indices = dic->music.indices; + break; + case IP3DBIDX_OBJECTS: + indices = dic->objects.indices; + break; + } + if (indices) { + return indices[index].idx_root; + } else { + return 0; + } } + +void dic_repr_index(dic_t* dic, int table, int index, FILE *fp) +{ + int i; + const dic_table_t* tbl = NULL; + const dic_index_t* idx = NULL; + + switch (table) { + case IP3DBIDX_MUSIC: + tbl = &dic->music; + break; + case IP3DBIDX_OBJECTS: + tbl = &dic->objects; + break; + } + + idx = &tbl->indices[index]; + for (i = 0;i < IP3DBIDX_MAX_KEYLEVEL;++i) { + int field = idx->fields[i]; + if (field == IP3DBF_MUSIC_NONE) { + break; + } + if (i != 0) { + fputc('-', fp); + } + fprints(fp, "%s", tbl->fields[field].name); + } +} Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-24 18:21:20 UTC (rev 198) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-25 07:46:57 UTC (rev 199) @@ -29,16 +29,24 @@ uint32_t type; uint32_t idx_root; ucs2char_t* name; -} dic_entry_t; +} dic_field_t; typedef struct { + uint32_t idx_root; + uint32_t offset; + int fields[IP3DBIDX_MAX_KEYLEVEL]; +} dic_index_t; + +typedef struct { int num_fields; - dic_entry_t *fields; -} dic_list_t; + dic_field_t *fields; + int num_indices; + dic_index_t *indices; +} dic_table_t; struct tag_dic_t { - dic_list_t music; - dic_list_t objects; + dic_table_t music; + dic_table_t objects; }; typedef struct tag_dic_t dic_t; @@ -46,7 +54,7 @@ void dic_finish(dic_t* dic); int dic_serialize(dic_t* dic, uint8_t* buffer, int is_storing); void dic_dump(dic_t* dic, FILE *fp); +uint32_t dic_get_idxroot(dic_t* dic, int table, int index); +void dic_repr_index(dic_t* dic, int table, int index, FILE *fp); -uint32_t dic_get_idxroot(uint8_t *buffer, int field); - #endif/*__IP3DB_DIC_H__*/ Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-24 18:21:20 UTC (rev 198) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-25 07:46:57 UTC (rev 199) @@ -104,7 +104,8 @@ uint32_t offset, node_t* node, ip3db_variant_t* key, - int* types, + dic_table_t* dic_table, + int index, int level, int flag, void *instance @@ -113,7 +114,8 @@ void idx_walk( uint8_t *buffer, uint32_t offset, - int *types, + dic_table_t* dic_table, + int index, int level, idx_walk_callback_t callback, void *instance @@ -121,7 +123,8 @@ { node_t node; ip3db_variant_t key; - int type = types[level]; + int field = dic_table->indices[index].fields[level]; + int type = dic_table->fields[field].type; uint8_t* p = buffer + offset; /* Read the node information. */ @@ -129,7 +132,7 @@ /* Descend to left children. */ if (node.left) { - idx_walk(buffer, node.left, types, level, callback, instance); + idx_walk(buffer, node.left, dic_table, index, level, callback, instance); } /* Read the key value. */ @@ -151,22 +154,25 @@ /* Invoke the callback function. */ if (callback && type) { - callback(buffer, offset, &node, &key, types, level, 1, instance); + callback(buffer, offset, &node, &key, dic_table, index, level, 1, instance); } /* Descend to the next key level if necessary. */ - if (level+1 < IP3DBIDX_MAX_KEYLEVEL && types[level+1]) { - idx_walk(buffer, node.leaf, types, level+1, callback, instance); + if (level+1 < IP3DBIDX_MAX_KEYLEVEL) { + int next_field = dic_table->indices[index].fields[level+1]; + if (next_field != -1) { + idx_walk(buffer, node.leaf, dic_table, index, level+1, callback, instance); + } } /* Invoke the callback function. */ if (callback && type) { - callback(buffer, offset, &node, &key, types, level, 0, instance); + callback(buffer, offset, &node, &key, dic_table, index, level, 0, instance); } /* Descend to right children. */ if (node.right) { - idx_walk(buffer, node.right, types, level, callback, instance); + idx_walk(buffer, node.right, dic_table, index, level, callback, instance); } } @@ -180,13 +186,17 @@ uint32_t offset, node_t* node, ip3db_variant_t* key, - int* types, + dic_table_t* dic_table, + int index, int level, int flag, void *instance ) { FILE *fp = (FILE*)instance; + int field = dic_table->indices[index].fields[level]; + int type = dic_table->fields[field].type; + int is_tail = (IP3DBIDX_MAX_KEYLEVEL <= level+1 || dic_table->indices[index].fields[level+1] == -1); int indent = 2 * (level + 1); if (flag) { @@ -217,14 +227,14 @@ } fprintf(fp, "\n"); - if (IP3DBIDX_MAX_KEYLEVEL <= level+1 || !types[level+1]) { + if (is_tail) { tail_t tail; memset(&tail, 0, sizeof(tail)); tail.next = node->leaf; fprinti(fp, indent); - fprintf(fp, " dat_offset: [\n", node->left); + fprintf(fp, " TAIL: [\n", node->left); while (tail.next) { uint8_t *p = buffer + tail.next; idx_serialize_tail(p, &tail, 0); @@ -242,7 +252,7 @@ return 0; } -int idx_dump(FILE *fpo, ip3db_t* db) +int idx_dump(uint8_t* buffer, dic_t* dic, FILE *fpo) { int i; header_t header; @@ -250,18 +260,26 @@ fprintf(fpo, "===== db.idx =====\n"); /* Dump the header. */ - idx_serialize_header(db->idx_buffer, &header, 0); + idx_serialize_header(buffer, &header, 0); fprintf(fpo, "size: 0x%08X\n", header.size); fprintf(fpo, "unknown1: 0x%08X\n", header.unknown1); fprintf(fpo, "unknown2: 0x%08X\n", header.unknown2); /* Dump the binary search trees. */ - for (i = 0;i < IP3DBIDX_LAST;++i) { - ip3db_index_param_t* index_param = ip3db_get_indexparam(i); - uint32_t idx_root = dic_get_idxroot(db->dic_buffer, i); - fprintf(fpo, "[%s]\n", index_param->name); - idx_walk(db->idx_buffer, idx_root, index_param->types, 0, idx_walkcb_dump, (void*)stdout); + for (i = 0;i < dic->music.num_indices;++i) { + uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_MUSIC, i); + fprintf(fpo, "["); + dic_repr_index(dic, IP3DBIDX_MUSIC, i, fpo); + fprintf(fpo, "]\n"); + idx_walk(buffer, idx_root, &dic->music, i, 0, idx_walkcb_dump, (void*)stdout); } + for (i = 0;i < dic->objects.num_indices;++i) { + uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_OBJECTS, i); + fprintf(fpo, "["); + dic_repr_index(dic, IP3DBIDX_OBJECTS, i, fpo); + fprintf(fpo, "]\n"); + idx_walk(buffer, idx_root, &dic->objects, i, 0, idx_walkcb_dump, (void*)stdout); + } fprintf(fpo, "\n"); return 0; Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.h 2006-12-24 18:21:20 UTC (rev 198) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.h 2006-12-25 07:46:57 UTC (rev 199) @@ -19,10 +19,11 @@ * */ -/* $Id:$ */ +/* $Id$ */ #ifndef __IP3DB_IDX_H__ #define __IP3DB_IDX_H__ +int idx_dump(uint8_t* buffer, dic_t* dic, FILE *fpo); #endif/*__IP3DB_IDX_H__*/ Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-24 18:21:20 UTC (rev 198) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-25 07:46:57 UTC (rev 199) @@ -34,26 +34,8 @@ #include "ip3db.h" #include "dic.h" #include "dat.h" +#include "idx.h" -static ip3db_index_param_t ip3db_index_param[IP3DBIDX_LAST] = { - {"Music.Title", 0x0086, {IP3DBVT_STRING, IP3DBVT_NONE, IP3DBVT_NONE}}, - {"Music.Rating", 0x00F8, {IP3DBVT_WORD, IP3DBVT_NONE, IP3DBVT_NONE}}, - {"Music.TrackNumber", 0x0152, {IP3DBVT_WORD, IP3DBVT_NONE, IP3DBVT_NONE}}, - {"Music.ChangedFlag", 0x022C, {IP3DBVT_BYTE, IP3DBVT_NONE, IP3DBVT_NONE}}, - {"Music.ClusM", 0x027A, {IP3DBVT_DWORD, IP3DBVT_NONE, IP3DBVT_NONE}}, - {"Music.UID", 0x031C, {IP3DBVT_DWORD, IP3DBVT_NONE, IP3DBVT_NONE}}, - {"Music.Genre-Artist-Title", 0x0352, {IP3DBVT_STRING, IP3DBVT_STRING, IP3DBVT_STRING}}, - {"Music.Artist-Album-TrackNumber", 0x0384, {IP3DBVT_STRING, IP3DBVT_STRING, IP3DBVT_WORD}}, - {"Music.Artist-TrackNumber", 0x03C2, {IP3DBVT_STRING, IP3DBVT_WORD, IP3DBVT_NONE}}, - {"Music.Artist-Title", 0x03F4, {IP3DBVT_STRING, IP3DBVT_STRING, IP3DBVT_NONE}}, - {"Music.Genre-Title", 0x041A, {IP3DBVT_STRING, IP3DBVT_STRING, IP3DBVT_NONE}}, - {"Music.Album-TrackNumber", 0x043E, {IP3DBVT_STRING, IP3DBVT_WORD, IP3DBVT_NONE}}, - {"Object.UID", 0x099A, {IP3DBVT_DWORD, IP3DBVT_NONE, IP3DBVT_NONE}}, - {"Object.FileType", 0x09F0, {IP3DBVT_WORD, IP3DBVT_NONE, IP3DBVT_NONE}}, - {"Object.ObjectName", 0x0A0E, {IP3DBVT_STRING, IP3DBVT_NONE, IP3DBVT_NONE}}, - {"Object.FileType-ParentUid-Properties", 0x0ACE, {IP3DBVT_WORD, IP3DBVT_DWORD, IP3DBVT_BYTE}}, -}; - void ip3db_variant_init(ip3db_variant_t* var, int type) { memset(var, 0, sizeof(*var)); @@ -68,11 +50,6 @@ ip3db_variant_init(var, IP3DBVT_NONE); } -ip3db_index_param_t* ip3db_get_indexparam(int field) -{ - return &ip3db_index_param[field]; -} - void ip3db_init(ip3db_t* db) { memset(db, 0, sizeof(*db)); @@ -140,6 +117,6 @@ dat_dump(db->dat, db->dic, fpo); /* Dump db.idx */ - idx_dump(fpo, db); + idx_dump(db->idx_buffer, db->dic, fpo); return 0; } Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-24 18:21:20 UTC (rev 198) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-25 07:46:57 UTC (rev 199) @@ -25,26 +25,6 @@ #define __IP3DB_IP3DB_H__ enum { - IP3DBIDX_MUSIC_TITLE, - IP3DBIDX_MUSIC_RATING, - IP3DBIDX_MUSIC_TRACKNUMBER, - IP3DBIDX_MUSIC_CHANGEDFLAG, - IP3DBIDX_MUSIC_CLUSM, - IP3DBIDX_MUSIC_UID, - IP3DBIDX_MUSIC_GENRE_ARTIST_TITLE, - IP3DBIDX_MUSIC_ARTIST_ALBUM_TRACKNUMBER, - IP3DBIDX_MUSIC_ARTIST_TRACKNUMBER, - IP3DBIDX_MUSIC_ARTIST_TITLE, - IP3DBIDX_MUSIC_GENRE_TITLE, - IP3DBIDX_MUSIC_ALBUM_TRACKNUMBER, - IP3DBIDX_OBJECT_UID, - IP3DBIDX_OBJECT_FILETYPE, - IP3DBIDX_OBJECT_OBJECTNAME, - IP3DBIDX_OBJECT_FILETYPE_PARENTUID_PROP, - IP3DBIDX_LAST -}; - -enum { IP3DBIDX_MAX_KEYLEVEL = 3, }; @@ -73,6 +53,7 @@ } ip3db_variant_t; enum { + IP3DBF_MUSIC_NONE = -1, IP3DBF_MUSIC_BEGIN = 0, IP3DBF_MUSIC_ARTIST = 0, IP3DBF_MUSIC_ALBUM, @@ -104,6 +85,7 @@ }; enum { + IP3DBF_OBJECTS_NONE = -1, IP3DBF_OBJECTS_BEGIN = 0, IP3DBF_OBJECTS_UID = 0, IP3DBF_OBJECTS_PARENTUID, @@ -119,15 +101,41 @@ IP3DBF_OBJECTS_LAST, }; +enum { + IP3DBIDX_MUSIC = 0, + IP3DBIDX_OBJECTS, +}; +enum { + IP3DBIDX_MUSIC_NONE = -1, + IP3DBIDX_MUSIC_BEGIN = 0, + IP3DBIDX_MUSIC_TITLE = 0, + IP3DBIDX_MUSIC_RATING, + IP3DBIDX_MUSIC_TRACKNUMBER, + IP3DBIDX_MUSIC_CHANGEDFLAG, + IP3DBIDX_MUSIC_CLUSM, + IP3DBIDX_MUSIC_UID, + IP3DBIDX_MUSIC_GENRE_ARTIST_TITLE, + IP3DBIDX_MUSIC_ARTIST_ALBUM_TRACKNUMBER, + IP3DBIDX_MUSIC_ARTIST_TRACKNUMBER, + IP3DBIDX_MUSIC_ARTIST_TITLE, + IP3DBIDX_MUSIC_GENRE_TITLE, + IP3DBIDX_MUSIC_ALBUM_TRACKNUMBER, + IP3DBIDX_MUSIC_LAST, +}; +enum { + IP3DBIDX_OBJECT_NONE = -1, + IP3DBIDX_OBJECT_BEGIN = 0, + IP3DBIDX_OBJECT_UID, + IP3DBIDX_OBJECT_FILETYPE, + IP3DBIDX_OBJECT_OBJECTNAME, + IP3DBIDX_OBJECT_FILETYPE_PARENTUID_PROP, + IP3DBIDX_OBJECT_LAST, +}; -typedef struct { - const char* name; - uint32_t dic_offset; - int types[IP3DBIDX_MAX_KEYLEVEL]; -} ip3db_index_param_t; + struct tag_dat_t; typedef struct tag_dat_t dat_t; struct tag_dic_t; typedef struct tag_dic_t dic_t; @@ -143,10 +151,6 @@ dic_t* dic; } ip3db_t; -int idx_dump(FILE *fpo, ip3db_t* db); - -ip3db_index_param_t* ip3db_get_indexparam(int field); - void ip3db_variant_init(ip3db_variant_t* var, int type); void ip3db_variant_finish(ip3db_variant_t* var); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-25 14:34:05
|
Revision: 200 http://svn.sourceforge.net/pmplib/?rev=200&view=rev Author: nyaochi Date: 2006-12-25 06:33:57 -0800 (Mon, 25 Dec 2006) Log Message: ----------- Implemented a record constructor for db.dat. Not tested yet. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/dat.h trunk/pmplib/lib/pmp_iriverplus3/dic.c trunk/pmplib/lib/pmp_iriverplus3/dic.h trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-25 07:46:57 UTC (rev 199) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-25 14:33:57 UTC (rev 200) @@ -39,6 +39,7 @@ #include <stdlib.h> #include <memory.h> #include <ucs2char.h> +#include <filepath.h> #include "serialize.h" #include "util.h" @@ -139,6 +140,12 @@ memset(list, 0, sizeof(*list)); } +static dat_entry_t *dat_list_expand(dat_list_t* list) +{ + list->entries = (dat_entry_t*)realloc(list->entries, sizeof(dat_entry_t) * (list->num_entries+1)); + return &list->entries[list->num_entries++]; +} + static void dat_list_finish(dat_list_t* list) { uint32_t i; @@ -230,3 +237,160 @@ dat_list_dump(&dat->musics, &dic->music, fp); fprintf(fp, "}\n"); } + +static int comp_pathname(const void *__x, const void *__y) +{ + const ip3db_sort_index_t* _x = (const ip3db_sort_index_t*)__x; + const ip3db_sort_index_t* _y = (const ip3db_sort_index_t*)__y; + const ip3db_variant_t* x = _x->base[_x->index]; + const ip3db_variant_t* y = _y->base[_y->index]; + int ret = ucs2cmp(x[IP3DBF_MUSIC_FILEPATH].value.str, y[IP3DBF_MUSIC_FILEPATH].value.str); + if (ret == 0) { + return ucs2cmp(x[IP3DBF_MUSIC_FILENAME].value.str, y[IP3DBF_MUSIC_FILENAME].value.str); + } else { + return ret; + } +} + +typedef struct { + ucs2char_t* path; + uint32_t uid; +} dircache_element_t; + +typedef struct { + int max_elems; + int num_elems; + dircache_element_t* elems; +} dircache_t; + +static void dircache_init(dircache_t* dc) +{ + memset(dc, 0, sizeof(*dc)); +} + +static void dircache_push(dircache_t* dc, const ucs2char_t* path, uint32_t uid) +{ + dircache_element_t* elem = NULL; + + if (dc->max_elems < dc->num_elems + 1) { + dc->elems = (dircache_element_t*)realloc(dc->elems, sizeof(dircache_element_t) * (dc->max_elems+1)); + memset(&dc->elems[dc->max_elems], 0, sizeof(dircache_element_t)); + ++dc->max_elems; + } + + elem = &dc->elems[dc->num_elems++]; + ucs2free(elem->path); + elem->path = ucs2dup(path); + elem->uid = uid; +} + +static void dircache_pop(dircache_t* dc, int i) +{ + ++i; + for (;i < dc->num_elems;++i) { + ucs2free(dc->elems[i].path); + memset(&dc->elems[i], 0, sizeof(dc->elems[0])); + } +} + +static int dircache_findprefix(dircache_t* dc, const ucs2char_t* path) +{ + int i = dc->num_elems; + while (--i >= 0) { + if (ucs2ncmp(path, dc->elems[i].path, ucs2len(dc->elems[i].path)) == 0) { + break; + } + } + return i; +} + +static dircache_element_t *dircache_get(dircache_t* dc, int i) +{ + return &dc->elems[i]; +} + + +void dat_construct(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records) +{ + int i, j; + dat_entry_t* entry; + uint32_t uid = 0; + static const uint32_t uid_root = 0xFFFFFFFF; + static const ucs2char_t ucs2cs_object_root[] = {'/','a','/',0}; + static const ucs2char_t ucs2cs_root[] = {PATHCHAR, 0}; + dat_list_t* dato = &dat->objects; + dat_list_t* datm = &dat->musics; + dircache_t dc; + ip3db_sort_index_t *si = (ip3db_sort_index_t*)malloc(sizeof(ip3db_sort_index_t) * num_records); + + dircache_init(&dc); + + /* Clear all entries. */ + dat_list_finish(dato); + dat_list_finish(datm); + + /* Append an entry for the root directory. */ + entry = dat_list_expand(dato); + dat_entry_init(entry, &dic->objects); + ip3db_variant_set_str(&entry->fields[IP3DBF_OBJECTS_OBJECTNAME], ucs2cs_object_root); + ip3db_variant_set_dword(&entry->fields[IP3DBF_OBJECTS_UID], uid_root); + + /* Register the root node to the directory cache. */ + dircache_push(&dc, ucs2cs_root, uid_root); + + for (i = 0;i < num_records;++i) { + si[i].base = records; + si[i].index = i; + } + qsort(si, num_records, sizeof(si[0]), comp_pathname); + + for (i = 0;i < num_records;++i) { + const ip3db_variant_t* record = records[si[i].index]; + const ucs2char_t* path = record[IP3DBF_MUSIC_FILEPATH].value.str; + const ucs2char_t* file = record[IP3DBF_MUSIC_FILENAME].value.str; + int i = dircache_findprefix(&dc, path); + const dircache_element_t* com = dircache_get(&dc, i); + const ucs2char_t* p = path + ucs2len(com->path); + uint32_t puid = com->uid; + + dircache_pop(&dc, i); + + while (p && *p) { + ucs2char_t tmp[MAX_PATH]; + const ucs2char_t* q = filepath_skip_one_directory(p); + uid = dato->num_entries; + + ucs2ncpy(tmp, p, q-p); + tmp[q-p] = 0; + + entry = dat_list_expand(dato); + dat_entry_init(entry, &dic->objects); + ip3db_variant_set_dword(&entry->fields[IP3DBF_OBJECTS_UID], uid); + ip3db_variant_set_dword(&entry->fields[IP3DBF_OBJECTS_PARENTUID], puid); + ip3db_variant_set_word(&entry->fields[IP3DBF_OBJECTS_FILETYPE], 1); + ip3db_variant_set_str(&entry->fields[IP3DBF_OBJECTS_OBJECTNAME], tmp); + + ucs2ncpy(tmp, path, q-path); + tmp[q-path] = 0; + dircache_push(&dc, tmp, uid); + + puid = uid; + p = q; + } + + uid = dato->num_entries; + entry = dat_list_expand(dato); + dat_entry_init(entry, &dic->objects); + ip3db_variant_set_dword(&entry->fields[IP3DBF_OBJECTS_UID], uid); + ip3db_variant_set_dword(&entry->fields[IP3DBF_OBJECTS_PARENTUID], puid); + ip3db_variant_set_word(&entry->fields[IP3DBF_OBJECTS_FILETYPE], 2); + ip3db_variant_set_str(&entry->fields[IP3DBF_OBJECTS_OBJECTNAME], file); + + entry = dat_list_expand(datm); + dat_entry_init(entry, &dic->music); + for (j = 0;j < entry->num_fields;++j) { + ip3db_variant_clone(&entry->fields[j], &record[j]); + } + ip3db_variant_set_dword(&entry->fields[IP3DBF_MUSIC_UID], uid); + } +} Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-25 07:46:57 UTC (rev 199) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-25 14:33:57 UTC (rev 200) @@ -49,4 +49,6 @@ size_t dat_serialize(dat_t* dat, const dic_t* dic, uint8_t* buffer, int is_storing); void dat_dump(dat_t* dat, const dic_t* dic, FILE *fp); +void dat_construct(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records); + #endif/*__IP3DB_DAT_H__*/ Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-25 07:46:57 UTC (rev 199) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-25 14:33:57 UTC (rev 200) @@ -64,6 +64,7 @@ {0, 0x0ACE, {IP3DBF_OBJECTS_FILETYPE, IP3DBF_OBJECTS_PARENTUID, IP3DBF_OBJECTS_PROPERTIES}}, }; + static void dic_field_init(dic_field_t* entry) { memset(entry, 0, sizeof(*entry)); @@ -186,9 +187,9 @@ void dic_dump(dic_t* dic, FILE *fp) { fprintf(fp, "===== db.dic =====\n"); - fprintf(fp, "MUSIC {\n"); + fprintf(fp, "MUSIC = {\n"); dic_table_dump(&dic->music, fp); - fprintf(fp, "OBJECTS {\n"); + fprintf(fp, "OBJECTS = {\n"); dic_table_dump(&dic->objects, fp); fprintf(fp, "\n"); } @@ -238,3 +239,191 @@ fprints(fp, "%s", tbl->fields[field].name); } } + +uint8_t *dic_get_template(long* size) +{ + static uint8_t dic_template[] = { + 0x00, 0x00, 0x0B, 0x16, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xEA, 0x00, 0x00, 0x04, 0x6E, 0x00, 0x00, 0x09, 0x72, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x03, 0x52, + 0x00, 0x4D, 0x00, 0x75, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, + 0x00, 0x73, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x41, 0x00, 0x6C, 0x00, 0x62, 0x00, 0x75, 0x00, 0x6D, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x86, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x65, 0x00, 0x6E, + 0x00, 0x72, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9E, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x54, 0x00, 0x69, 0x00, 0x74, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xBC, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6C, + 0x00, 0x65, 0x00, 0x50, 0x00, 0x61, 0x00, 0x74, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDA, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6C, 0x00, 0x65, + 0x00, 0x4E, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x75, 0x00, 0x72, 0x00, 0x61, 0x00, 0x74, + 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x67, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, + 0x00, 0x73, 0x00, 0x65, 0x00, 0x43, 0x00, 0x6F, 0x00, 0x75, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x52, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x69, + 0x00, 0x6C, 0x00, 0x65, 0x00, 0x46, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x6D, 0x00, 0x61, 0x00, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x76, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x72, 0x00, 0x61, 0x00, 0x63, 0x00, 0x6B, 0x00, 0x4E, 0x00, 0x75, 0x00, 0x6D, 0x00, 0x62, + 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x01, 0x8A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x44, 0x00, 0x72, 0x00, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA2, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x79, 0x00, 0x72, 0x00, 0x69, 0x00, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xC0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, + 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x68, 0x00, 0x61, 0x00, 0x73, 0x00, 0x65, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xEE, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x72, + 0x00, 0x6F, 0x00, 0x74, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x6E, + 0x00, 0x53, 0x00, 0x74, 0x00, 0x61, 0x00, 0x74, 0x00, 0x75, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x61, 0x00, 0x6D, + 0x00, 0x70, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x52, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x2C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x69, + 0x00, 0x74, 0x00, 0x52, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x02, 0x50, + 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x68, 0x00, 0x61, 0x00, 0x6E, + 0x00, 0x67, 0x00, 0x65, 0x00, 0x64, 0x00, 0x46, 0x00, 0x6C, 0x00, 0x61, 0x00, 0x67, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x7A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x75, + 0x00, 0x64, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x57, 0x00, 0x41, 0x00, 0x56, 0x00, 0x45, 0x00, 0x43, + 0x00, 0x6F, 0x00, 0x64, 0x00, 0x65, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x02, 0x92, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x6C, 0x00, 0x75, 0x00, 0x73, 0x00, 0x4D, + 0x00, 0x00, 0x00, 0x00, 0x02, 0xAA, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, + 0x00, 0x6C, 0x00, 0x75, 0x00, 0x73, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x02, 0xCE, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x6C, 0x00, 0x62, 0x00, 0x75, 0x00, 0x6D, + 0x00, 0x41, 0x00, 0x72, 0x00, 0x74, 0x00, 0x50, 0x00, 0x6F, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, + 0x02, 0xF8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x00, 0x72, 0x00, 0x67, + 0x00, 0x52, 0x00, 0x65, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x61, 0x00, 0x73, 0x00, 0x65, 0x00, 0x44, + 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x03, 0x1C, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x6C, 0x00, 0x62, 0x00, 0x75, 0x00, 0x6D, 0x00, 0x41, + 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x03, 0x30, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x49, 0x00, 0x44, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, 0x61, + 0x00, 0x74, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x67, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6D, 0x00, 0x65, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x84, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, + 0x00, 0x65, 0x00, 0x6E, 0x00, 0x72, 0x00, 0x65, 0x00, 0x00, 0x00, 0x41, 0x00, 0x72, 0x00, 0x74, + 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00, 0x00, 0x00, 0x54, 0x00, 0x69, 0x00, 0x74, 0x00, 0x6C, + 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x03, 0xC2, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x41, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00, 0x00, 0x00, 0x41, + 0x00, 0x6C, 0x00, 0x62, 0x00, 0x75, 0x00, 0x6D, 0x00, 0x00, 0x00, 0x54, 0x00, 0x72, 0x00, 0x61, + 0x00, 0x63, 0x00, 0x6B, 0x00, 0x4E, 0x00, 0x75, 0x00, 0x6D, 0x00, 0x62, 0x00, 0x65, 0x00, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x03, 0xF4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, + 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00, 0x00, 0x00, 0x54, 0x00, 0x72, + 0x00, 0x61, 0x00, 0x63, 0x00, 0x6B, 0x00, 0x4E, 0x00, 0x75, 0x00, 0x6D, 0x00, 0x62, 0x00, 0x65, + 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x04, 0x1A, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x41, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00, 0x00, 0x00, 0x54, + 0x00, 0x69, 0x00, 0x74, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x04, 0x3E, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x72, 0x00, 0x65, + 0x00, 0x00, 0x00, 0x54, 0x00, 0x69, 0x00, 0x74, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x6C, 0x00, 0x62, + 0x00, 0x75, 0x00, 0x6D, 0x00, 0x00, 0x00, 0x54, 0x00, 0x72, 0x00, 0x61, 0x00, 0x63, 0x00, 0x6B, + 0x00, 0x4E, 0x00, 0x75, 0x00, 0x6D, 0x00, 0x62, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x6C, 0x00, 0x62, 0x00, 0x75, 0x00, 0x6D, + 0x00, 0x00, 0x00, 0x00, 0x04, 0xB0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, + 0x00, 0x69, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x50, 0x00, 0x61, 0x00, 0x74, 0x00, 0x68, 0x00, 0x00, + 0x00, 0x00, 0x04, 0xCE, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x69, + 0x00, 0x6C, 0x00, 0x65, 0x00, 0x4E, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x04, 0xE8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x72, 0x00, 0x74, + 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x6C, 0x00, 0x62, 0x00, 0x75, 0x00, 0x6D, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x65, + 0x00, 0x6E, 0x00, 0x72, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x05, 0x32, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x6D, 0x00, 0x61, 0x00, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x56, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, + 0x00, 0x61, 0x00, 0x6D, 0x00, 0x70, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x57, 0x00, 0x69, 0x00, 0x64, + 0x00, 0x74, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x05, 0x7C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x53, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x70, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x48, + 0x00, 0x65, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x05, 0x9C, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x53, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x70, + 0x00, 0x6C, 0x00, 0x65, 0x00, 0x50, 0x00, 0x6F, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x05, 0xBE, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x70, + 0x00, 0x6C, 0x00, 0x65, 0x00, 0x53, 0x00, 0x69, 0x00, 0x7A, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x05, 0xD6, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x43, 0x00, 0x6C, 0x00, 0x75, + 0x00, 0x73, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x55, 0x00, 0x49, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, + 0x07, 0x36, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x50, 0x00, 0x68, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6C, + 0x00, 0x65, 0x00, 0x50, 0x00, 0x61, 0x00, 0x74, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x06, 0x4A, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6C, 0x00, 0x65, + 0x00, 0x4E, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, 0x62, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x69, 0x00, 0x64, 0x00, 0x74, 0x00, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x7C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x00, 0x65, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x06, 0x96, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x6D, + 0x00, 0x61, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x06, 0xBA, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x53, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x70, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x57, + 0x00, 0x69, 0x00, 0x64, 0x00, 0x74, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x06, 0xE0, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x70, 0x00, 0x6C, + 0x00, 0x65, 0x00, 0x48, 0x00, 0x65, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 0x00, 0x74, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x53, 0x00, 0x61, + 0x00, 0x6D, 0x00, 0x70, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x50, 0x00, 0x6F, 0x00, 0x73, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x22, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, 0x61, + 0x00, 0x6D, 0x00, 0x70, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x53, 0x00, 0x69, 0x00, 0x7A, 0x00, 0x65, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x55, + 0x00, 0x49, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xD4, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, + 0x00, 0x65, 0x00, 0x66, 0x00, 0x65, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x63, 0x00, 0x65, + 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x07, 0x8C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x50, 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x43, 0x00, 0x6C, + 0x00, 0x75, 0x00, 0x73, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x07, 0xB2, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x43, 0x00, 0x68, 0x00, 0x69, 0x00, 0x6C, + 0x00, 0x64, 0x00, 0x43, 0x00, 0x6C, 0x00, 0x75, 0x00, 0x73, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, + 0x00, 0x69, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x46, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x6D, 0x00, 0x61, + 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, 0x69, + 0x00, 0x64, 0x00, 0x65, 0x00, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x08, 0x24, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x75, 0x00, 0x64, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x53, + 0x00, 0x61, 0x00, 0x6D, 0x00, 0x70, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x52, 0x00, 0x61, 0x00, 0x74, + 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x41, 0x00, 0x75, 0x00, 0x64, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x42, 0x00, 0x69, 0x00, 0x74, + 0x00, 0x52, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x08, 0x62, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x69, 0x00, 0x64, 0x00, 0x74, 0x00, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x7C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, + 0x00, 0x65, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x08, 0xA2, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x6F, 0x00, 0x74, 0x00, 0x61, + 0x00, 0x6C, 0x00, 0x42, 0x00, 0x69, 0x00, 0x74, 0x00, 0x52, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, + 0x00, 0x00, 0x00, 0x00, 0x08, 0xC8, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, + 0x00, 0x69, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6F, 0x00, 0x42, 0x00, 0x69, 0x00, 0x74, 0x00, 0x52, + 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x09, 0x06, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x72, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x73, + 0x00, 0x50, 0x00, 0x65, 0x00, 0x72, 0x00, 0x54, 0x00, 0x68, 0x00, 0x6F, 0x00, 0x75, 0x00, 0x73, + 0x00, 0x61, 0x00, 0x6E, 0x00, 0x64, 0x00, 0x53, 0x00, 0x65, 0x00, 0x63, 0x00, 0x6F, 0x00, 0x6E, + 0x00, 0x64, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x09, 0x34, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x56, 0x00, 0x69, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6F, 0x00, 0x46, 0x00, 0x6F, + 0x00, 0x75, 0x00, 0x72, 0x00, 0x43, 0x00, 0x43, 0x00, 0x43, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x65, + 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x09, 0x5E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x41, 0x00, 0x75, 0x00, 0x64, 0x00, 0x69, 0x00, 0x6F, 0x00, 0x57, 0x00, 0x41, 0x00, 0x56, + 0x00, 0x45, 0x00, 0x43, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x65, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x55, 0x00, 0x49, 0x00, 0x44, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x09, 0x9A, 0x00, 0x00, 0x0A, 0xCE, 0x00, 0x4F, 0x00, 0x62, 0x00, 0x6A, + 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x09, 0xAE, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x49, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, + 0x09, 0xCE, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x61, 0x00, 0x72, + 0x00, 0x65, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x55, 0x00, 0x69, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, + 0x09, 0xF0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x72, 0x00, 0x6F, + 0x00, 0x70, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x65, 0x00, 0x73, 0x00, 0x00, + 0x00, 0x00, 0x0A, 0x0E, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x69, + 0x00, 0x6C, 0x00, 0x65, 0x00, 0x54, 0x00, 0x79, 0x00, 0x70, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x00, 0x62, 0x00, 0x6A, + 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x4E, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x00, + 0x00, 0x00, 0x0A, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x00, 0x61, + 0x00, 0x6D, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x64, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x53, 0x00, 0x69, 0x00, 0x7A, + 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x82, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x44, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x43, 0x00, 0x72, 0x00, 0x65, 0x00, 0x61, + 0x00, 0x00, 0x00, 0x00, 0x0A, 0x9A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, + 0x00, 0x6F, 0x00, 0x77, 0x00, 0x49, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xB4, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x55, 0x00, 0x4F, 0x00, 0x49, 0x00, 0x44, + 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x55, 0x00, 0x4F, 0x00, 0x49, 0x00, 0x44, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x69, 0x00, 0x6C, + 0x00, 0x65, 0x00, 0x54, 0x00, 0x79, 0x00, 0x70, 0x00, 0x65, 0x00, 0x00, 0x00, 0x50, 0x00, 0x61, + 0x00, 0x72, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x55, 0x00, 0x69, 0x00, 0x64, 0x00, 0x00, + 0x00, 0x50, 0x00, 0x72, 0x00, 0x6F, 0x00, 0x70, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, + 0x00, 0x65, 0x00, 0x73, 0x00, 0x00, + }; + if (size) { + *size = sizeof(dic_template) / sizeof(dic_template[0]); + } + return dic_template; +} Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-25 07:46:57 UTC (rev 199) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-25 14:33:57 UTC (rev 200) @@ -56,5 +56,6 @@ void dic_dump(dic_t* dic, FILE *fp); uint32_t dic_get_idxroot(dic_t* dic, int table, int index); void dic_repr_index(dic_t* dic, int table, int index, FILE *fp); +uint8_t *dic_get_template(long* size); #endif/*__IP3DB_DIC_H__*/ Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-25 07:46:57 UTC (rev 199) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-25 14:33:57 UTC (rev 200) @@ -284,3 +284,4 @@ fprintf(fpo, "\n"); return 0; } + Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-25 07:46:57 UTC (rev 199) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-25 14:33:57 UTC (rev 200) @@ -50,11 +50,66 @@ ip3db_variant_init(var, IP3DBVT_NONE); } +void ip3db_variant_set_byte(ip3db_variant_t* var, uint8_t val) +{ + var->type = IP3DBVT_BYTE; + var->value.byte = val; +} + +void ip3db_variant_set_word(ip3db_variant_t* var, uint16_t val) +{ + var->type = IP3DBVT_WORD; + var->value.word = val; +} + +void ip3db_variant_set_dword(ip3db_variant_t* var, uint32_t val) +{ + var->type = IP3DBVT_DWORD; + var->value.dword = val; +} + +void ip3db_variant_set_str(ip3db_variant_t* var, const ucs2char_t* val) +{ + var->type = IP3DBVT_STRING; + ucs2free(var->value.str); + var->value.str = ucs2dup(val); +} + +void ip3db_variant_clone(ip3db_variant_t* dst, const ip3db_variant_t* src) +{ + switch (dst->type = src->type) { + case IP3DBVT_BYTE: + dst->value.byte = src->value.byte; + break; + case IP3DBVT_WORD: + dst->value.word = src->value.word; + break; + case IP3DBVT_DWORD: + dst->value.dword = src->value.dword; + break; + case IP3DBVT_STRING: + ucs2free(dst->value.str); + if (src->value.str) { + dst->value.str = ucs2dup(src->value.str); + } else { + dst->value.str = 0; + } + break; + } +} + void ip3db_init(ip3db_t* db) { + uint8_t *dic_template = NULL; + memset(db, 0, sizeof(*db)); db->dat = dat_new(); db->dic = dic_new(); + + dic_template = dic_get_template(&db->dic_size); + db->dic_buffer = (uint8_t*)malloc(db->dic_size); + memcpy(db->dic_buffer, dic_template, db->dic_size); + dic_serialize(db->dic, db->dic_buffer, 0); } void ip3db_finish(ip3db_t* db) @@ -120,3 +175,26 @@ idx_dump(db->idx_buffer, db->dic, fpo); return 0; } + +result_t ip3db_set(ip3db_t* db, const ip3db_music_record_t* records, int num_records) +{ + /* Construct Objects table in db.dat */ + dat_construct(db->dat, db->dic, records, num_records); + + /* Construct Music table in db.dat */ + + /* Construct db.idx */ + + /* Update db.dic */ + + return 0; +} + +void ip3db_record_init(ip3db_t* db, ip3db_music_record_t* record) +{ + int i; + ip3db_variant_t* var = (ip3db_variant_t*)record; + for (i = 0;i < IP3DBF_MUSIC_LAST;++i) { + ip3db_variant_init(&var[i], db->dic->music.fields[i].type); + } +} Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-25 07:46:57 UTC (rev 199) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-25 14:33:57 UTC (rev 200) @@ -84,6 +84,14 @@ IP3DBF_MUSIC_LAST, }; +typedef ip3db_variant_t ip3db_music_record_t[IP3DBF_MUSIC_LAST]; + +typedef struct { + const ip3db_music_record_t* base; + int index; +} ip3db_sort_index_t; + + enum { IP3DBF_OBJECTS_NONE = -1, IP3DBF_OBJECTS_BEGIN = 0, @@ -149,14 +157,23 @@ dat_t* dat; dic_t* dic; + } ip3db_t; void ip3db_variant_init(ip3db_variant_t* var, int type); void ip3db_variant_finish(ip3db_variant_t* var); +void ip3db_variant_set_byte(ip3db_variant_t* var, uint8_t val); +void ip3db_variant_set_word(ip3db_variant_t* var, uint16_t val); +void ip3db_variant_set_dword(ip3db_variant_t* var, uint32_t val); +void ip3db_variant_set_str(ip3db_variant_t* var, const ucs2char_t* val); +void ip3db_variant_clone(ip3db_variant_t* dst, const ip3db_variant_t* src); void ip3db_init(ip3db_t* db); void ip3db_finish(ip3db_t* db); result_t ip3db_read(ip3db_t* db, const ucs2char_t* datfn, const ucs2char_t* dicfn, const ucs2char_t* idxfn); result_t ip3db_dump(ip3db_t* db, FILE *fpo); +void ip3db_record_init(ip3db_t* db, ip3db_music_record_t* record); +result_t ip3db_set(ip3db_t* db, const ip3db_music_record_t* records, int num_records); + #endif /*_IP3DB_IP3DB_H__*/ Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-25 07:46:57 UTC (rev 199) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-25 14:33:57 UTC (rev 200) @@ -65,7 +65,7 @@ "iriver_e10_ums_1.04", "E10 UMS", "UM", "1.04", "1.04", "System\\E10.SYS", "System\\db.dat", "System\\db.dic", "System\\db.idx", - "\\", "Playlists\\", + "", "Playlists\\", ".plp", }, { @@ -503,9 +503,30 @@ static result_t pmpdb_set(pmpdb_t* pmpdb, const pmp_record_t* records, uint32_t num_records) { + int i; pmpdb_internal_t* pmpdbi = (pmpdb_internal_t*)pmpdb->instance; pmp_internal_t* pmpi = (pmp_internal_t*)pmpdb->pmp->instance; - return PMP_NOTIMPLIMENTED; + ucs2char_t *path_to_root = alloca(sizeof(ucs2char_t) * (ucs2len(pmpi->env.path_to_root)+1)); + + ip3db_music_record_t* array = (ip3db_music_record_t*)malloc(sizeof(ip3db_music_record_t) * num_records); + + ucs2cpy(path_to_root, pmpi->env.path_to_root); + filepath_removeslash(path_to_root); + + for (i = 0;i < num_records;++i) { + const pmp_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], src->filename + ucs2len(path_to_root)); + filepath_remove_filespec(dst[IP3DBF_MUSIC_FILEPATH].value.str); + filepath_addslash(dst[IP3DBF_MUSIC_FILEPATH].value.str); + filepath_encode(dst[IP3DBF_MUSIC_FILEPATH].value.str); + ip3db_variant_set_str(&dst[IP3DBF_MUSIC_FILENAME], filepath_skippath(src->filename)); + } + ip3db_set(&pmpdbi->ip3db, array, num_records); + free(array); + return 0; //return ip2db_set(&pmpdbi->ip2db, records, num_records, pmpi->env.path_to_root); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-25 15:15:35
|
Revision: 201 http://svn.sourceforge.net/pmplib/?rev=201&view=rev Author: nyaochi Date: 2006-12-25 07:15:36 -0800 (Mon, 25 Dec 2006) Log Message: ----------- Implemented pmpdb_write() interface for pmp_iriverplus3. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-25 14:33:57 UTC (rev 200) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-25 15:15:36 UTC (rev 201) @@ -84,7 +84,12 @@ switch (var->type) { case IP3DBVT_STRING: if (is_storing) { - p += (serialize_ucs2be_string_var(p, var->value.str, is_storing) + 1) * sizeof(ucs2char_t); + if (var->value.str) { + p += (serialize_ucs2be_string_var(p, var->value.str, is_storing) + 1) * sizeof(ucs2char_t); + } else { + ucs2char_t v = 0; + p += serialize_ucs2be(p, &v, is_storing); + } } else { p += (serialize_ucs2be_string_var_alloc(p, &var->value.str) + 1) * sizeof(ucs2char_t); } @@ -162,11 +167,13 @@ uint8_t *p = buffer; uint8_t *q = buffer + 0x00020000 - sizeof(uint32_t); + /* Serialize the header (with a dummy size for writing). */ p += serialize_uint32be(p, &list->size, is_storing); p += serialize_uint32be(p, &list->num_entries, is_storing); p += serialize_uint32be(p, &list->unknown1, is_storing); p += serialize_uint32be(p, &list->unknown2, is_storing); + /* Initialize fields when reading. */ if (!is_storing) { free(list->entries); list->entries = (dat_entry_t*)calloc(list->num_entries, sizeof(dat_entry_t)); @@ -175,12 +182,20 @@ } } + /* Serialize entries in this table. */ for (i = 0;i < list->num_entries;++i) { dat_entry_t* entry = &list->entries[i]; + entry->offset = (uint32_t)(p - buffer); /* compute the current offset address */ p += dat_entry_serialize(entry, p, q, is_storing); q -= sizeof(uint32_t); } + /* Write the final size when writing. */ + if (is_storing) { + uint32_t size = (uint32_t)(p - buffer); + serialize_uint32be(buffer, &size, is_storing); + } + return (size_t)(p - buffer); } Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-25 14:33:57 UTC (rev 200) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-25 15:15:36 UTC (rev 201) @@ -163,6 +163,55 @@ return 0; } +result_t ip3db_write(ip3db_t* db, const ucs2char_t* datfn, const ucs2char_t* dicfn, const ucs2char_t* idxfn) +{ + FILE *fp = 0; + + free(db->dat_buffer); + free(db->idx_buffer); + + db->dat_size = 0x00040000; + //db->dat_buffer = (uint8_t*)calloc(db->dat_size, sizeof(uint8_t)); + db->dat_buffer = (uint8_t*)malloc(db->dat_size); + + if (dat_serialize(db->dat, db->dic, db->dat_buffer, 1) != 0) { + ip3db_finish(db); + return 1; + } + + if (dic_serialize(db->dic, db->dic_buffer, 1) != 0) { + ip3db_finish(db); + return 1; + } + + fp = ucs2fopen(datfn, "wb"); + if (!fp) { + return 1; + } + fwrite(db->dat_buffer, 1, db->dat_size, fp); + fclose(fp); + + /* + fp = ucs2fopen(dicfn, "rb"); + if (!fp) { + ip3db_finish(db); + return 1; + } + fread_all(fp, &db->dic_buffer, &db->dic_size); + fclose(fp); + + fp = ucs2fopen(idxfn, "rb"); + if (!fp) { + ip3db_finish(db); + return 1; + } + fread_all(fp, &db->idx_buffer, &db->idx_size); + fclose(fp); +*/ + + return 0; +} + result_t ip3db_dump(ip3db_t* db, FILE *fpo) { /* Dump db.dic */ Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-25 14:33:57 UTC (rev 200) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-25 15:15:36 UTC (rev 201) @@ -497,8 +497,12 @@ { pmpdb_internal_t* pmpdbi = (pmpdb_internal_t*)pmpdb->instance; pmp_internal_t* pmpi = (pmp_internal_t*)pmpdb->pmp->instance; - return PMP_NOTIMPLIMENTED; - //return ip2db_write(&pmpdbi->ip2db, pmpi->env.dat_filename, pmpi->env.idx_filename); + return ip3db_write( + &pmpdbi->ip3db, + pmpi->env.dat_filename, + pmpi->env.dic_filename, + pmpi->env.idx_filename + ); } static result_t pmpdb_set(pmpdb_t* pmpdb, const pmp_record_t* records, uint32_t num_records) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-27 11:40:39
|
Revision: 203 http://svn.sourceforge.net/pmplib/?rev=203&view=rev Author: nyaochi Date: 2006-12-27 03:40:38 -0800 (Wed, 27 Dec 2006) Log Message: ----------- Incremental commit: implemented the generation routine for db.idx, which will be tested and debugged later. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dic.c trunk/pmplib/lib/pmp_iriverplus3/dic.h trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/idx.h trunk/pmplib/lib/pmp_iriverplus3/ip3db.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-27 08:08:26 UTC (rev 202) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-27 11:40:38 UTC (rev 203) @@ -212,6 +212,22 @@ } } +void dic_set_idxroot(dic_t* dic, int table, int index, uint32_t root) +{ + dic_index_t* indices = NULL; + switch (table) { + case IP3DBIDX_MUSIC: + indices = dic->music.indices; + break; + case IP3DBIDX_OBJECTS: + indices = dic->objects.indices; + break; + } + if (indices) { + indices[index].idx_root = root; + } +} + void dic_repr_index(dic_t* dic, int table, int index, FILE *fp) { int i; Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-27 08:08:26 UTC (rev 202) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-27 11:40:38 UTC (rev 203) @@ -55,6 +55,7 @@ int dic_serialize(dic_t* dic, uint8_t* buffer, int is_storing); void dic_dump(dic_t* dic, FILE *fp); uint32_t dic_get_idxroot(dic_t* dic, int table, int index); +void dic_set_idxroot(dic_t* dic, int table, int index, uint32_t root); void dic_repr_index(dic_t* dic, int table, int index, FILE *fp); uint8_t *dic_get_template(long* size); Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-27 08:08:26 UTC (rev 202) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-27 11:40:38 UTC (rev 203) @@ -284,16 +284,32 @@ return COMP(*x, *y); } -static int avl_insert_key(avl_t* avl, const void* key, size_t size, int type, uint32_t* offset, uint32_t* root) +static int avl_insert_key(avl_t* avl, const void* key, int type, uint32_t* offset, uint32_t* root) { int ret = 0; + static avl_comp_t comp[] = {NULL, avl_comp_byte, avl_comp_word, avl_comp_dword, avl_comp_ucs2string}; uint32_t offset_prev = avl_current(avl); uint32_t offset_this = avlnode_new(avl); - uint32_t offset_key = avl_allocate(avl, (uint32_t)size); - void *pkey = avlnode(avl, offset_key); - static avl_comp_t comp[] = {NULL, avl_comp_byte, avl_comp_word, avl_comp_dword, avl_comp_ucs2string}; + size_t size = 0; + uint32_t offset_key = 0; - memcpy(pkey, key, size); + switch (type) { + case IP3DBVT_BYTE: + size = sizeof(uint8_t); + break; + case IP3DBVT_WORD: + size = sizeof(uint16_t); + break; + case IP3DBVT_DWORD: + size = sizeof(uint32_t); + break; + case IP3DBVT_STRING: + size = (ucs2len((const ucs2char_t*)key) + 1) * sizeof(ucs2char_t); + break; + } + + offset_key = avl_allocate(avl, (uint32_t)size); + memcpy(avlnode(avl, offset_key), key, size); ret = avl_insert(avl, root, &offset_this, comp[type]); if (ret != -1) { /* A new key. */ @@ -307,10 +323,10 @@ } } -static int avl_insert_keydata(avl_t* avl, const void* key, size_t size, int type, uint32_t data, uint32_t* root) +static int avl_insert_keydata(avl_t* avl, const void* key, int type, uint32_t data, uint32_t* root) { uint32_t offset = 0; - int ret = avl_insert_key(avl, key, size, type, &offset, root); + int ret = avl_insert_key(avl, key, type, &offset, root); avlnode_t* node = avlnode(avl, offset); uint32_t offset_tail = avltail_new(avl); avltail_t* tail = (avltail_t*)avlnode(avl, offset_tail); @@ -327,6 +343,14 @@ *value = tmp; } +static void to_uint16be(uint16_t* value) +{ + uint16_t tmp = *value; + uint8_t* dst = (uint8_t*)value; + dst[0] = (uint8_t)(tmp >> 8); + dst[1] = (uint8_t)(tmp & 0xFF); +} + static void from_uint32be(uint32_t* value) { uint8_t* src = (uint8_t*)value; @@ -334,6 +358,16 @@ *value = tmp; } +static void to_uint32be(uint32_t* value) +{ + uint32_t tmp = *value; + uint8_t* dst = (uint8_t*)value; + dst[0] = (uint8_t)(tmp >> 24); + dst[1] = (uint8_t)(tmp >> 16); + dst[2] = (uint8_t)(tmp >> 8); + dst[3] = (uint8_t)(tmp & 0xFF); +} + static void from_ucs2be_string(ucs2char_t* value) { while (*value) { @@ -342,12 +376,12 @@ } } -static void from_be_avlnode(avlnode_t* node) +static void to_ucs2be_string(ucs2char_t* value) { - from_uint32be(&node->left); - from_uint32be(&node->right); - from_uint32be(&node->balance); - from_uint32be(&node->tail); + while (*value) { + to_uint16be((uint16_t*)value); + value++; + } } static void from_be_avltree(avl_t* avl, uint32_t offset, dic_table_t* dic_table, int index, int level) @@ -357,7 +391,10 @@ int type = dic_table->fields[field].type; /* Convert the current node. */ - from_be_avlnode(node); + from_uint32be(&node->left); + from_uint32be(&node->right); + from_uint32be(&node->balance); + from_uint32be(&node->tail); /* Descend to the left node. */ if (node->left) { @@ -404,6 +441,66 @@ } } +static void to_be_avltree(avl_t* avl, uint32_t offset, dic_table_t* dic_table, int index, int level) +{ + avlnode_t* nbe = avlnode(avl, offset); + avlnode_t node = *nbe; + int field = dic_table->indices[index].fields[level]; + int type = dic_table->fields[field].type; + + /* Convert the current node. */ + to_uint32be(&nbe->left); + to_uint32be(&nbe->right); + to_uint32be(&nbe->balance); + to_uint32be(&nbe->tail); + + /* Descend to the left node. */ + if (node.left) { + to_be_avltree(avl, node.left, dic_table, index, level); + } + + /* Convert the key value. */ + switch (type) { + case IP3DBVT_BYTE: + break; + case IP3DBVT_WORD: + to_uint16be((uint16_t*)(nbe+1)); + break; + case IP3DBVT_DWORD: + to_uint32be((uint32_t*)(nbe+1)); + break; + case IP3DBVT_STRING: + to_ucs2be_string((ucs2char_t*)(nbe+1)); + break; + } + + /* Convert the sub AVL trees or tail. */ + if (node.tail) { + if (level+1 < IP3DBIDX_MAX_KEYLEVEL && dic_table->indices[index].fields[level+1] != -1) { + /* Convert the AVL tree in the next level. */ + to_be_avltree(avl, node.tail, dic_table, index, level+1); + } else { + /* Convert the tail. */ + avltail_t* tbe = (avltail_t*)avlnode(avl, node.tail); + avltail_t tail = *tbe; + for (;;) { + from_uint32be(&tbe->next); + from_uint32be(&tbe->data); + if (!tail.next) { + break; + } + tbe = (avltail_t*)avlnode(avl, tail.next); + tail = *tbe; + } + } + } + + /* Descend to the right node. */ + if (node.right) { + to_be_avltree(avl, node.right, dic_table, index, level); + } +} + static void fprinti(FILE *fp, int n) { while (n--) fputc(' ', fp); @@ -556,6 +653,34 @@ return 0; } +result_t idx_write(idx_t* idx, dic_t* dic, FILE *fpo) +{ + int i; + idx_header_t* header = (idx_header_t*)idx->buffer; + + /* Convert the byte order of the header from big endian to the native one. */ + to_uint32be(&header->size); + to_uint32be(&header->unknown1); + to_uint32be(&header->unknown2); + + /* Convert the byte order of AVL trees. */ + for (i = 0;i < dic->music.num_indices;++i) { + uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_MUSIC, i); + to_be_avltree(idx->avl, idx_root, &dic->music, i, 0); + } + for (i = 0;i < dic->objects.num_indices;++i) { + uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_OBJECTS, i); + to_be_avltree(idx->avl, idx_root, &dic->objects, i, 0); + } + + /* Read the whole data at a time. */ + if (fwrite(idx->buffer, 1, idx->max_size, fpo) != idx->max_size) { + return 1; + } + + return 0; +} + result_t idx_dump(idx_t* idx, dic_t* dic, FILE *fpo) { int i; @@ -587,3 +712,56 @@ fprintf(fpo, "\n"); return 0; } + +static void idx_insert_dat(idx_t* idx, dic_table_t* dictbl, uint32_t* root, dat_entry_t* entry, int index, int level) +{ + uint32_t offset = 0; + int field = dictbl->indices[index].fields[level]; + int type = dictbl->fields[field].type; + int ret = avl_insert_key(idx->avl, &entry->fields[field].value, type, &offset, root); + if (level+1 < IP3DBIDX_MAX_KEYLEVEL && dictbl->indices[index].fields[level+1] != -1) { + avlnode_t* node = avlnode(idx->avl, offset); + idx_insert_dat(idx, dictbl, &node->tail, entry, index, level+1); + } else { + avlnode_t* node = avlnode(idx->avl, offset); + uint32_t offset_tail = avltail_new(idx->avl); + avltail_t* tail = (avltail_t*)avlnode(idx->avl, offset_tail); + tail->data = entry->offset; + tail->next = node->tail; + node->tail = offset_tail; + } +} + +static void idx_construct_index(idx_t* idx, dic_table_t* dictbl, dat_list_t* list, uint32_t* root, int index) +{ + uint32_t i; + + for (i = 0;i < list->num_entries;++i) { + dat_entry_t* entry = &list->entries[i]; + idx_insert_dat(idx, dictbl, root, entry, index, 0); + } +} + +result_t idx_construct(idx_t* idx, dic_t* dic, dat_t* dat) +{ + int index; + + memset(idx->buffer, 0, idx->max_size); + idx->avl->buffer = idx->buffer; + idx->avl->offset = sizeof(idx_header_t); + idx->avl->size = idx->max_size; + + for (index = 0;index < dic->music.num_indices;++index) { + uint32_t root = dic_get_idxroot(dic, IP3DBIDX_MUSIC, index); + idx_construct_index(idx, &dic->music, &dat->musics, &root, index); + dic_set_idxroot(dic, IP3DBIDX_MUSIC, index, root); + } + + for (index = 0;index < dic->objects.num_indices;++index) { + uint32_t root = dic_get_idxroot(dic, IP3DBIDX_OBJECTS, index); + idx_construct_index(idx, &dic->objects, &dat->objects, &root, index); + dic_set_idxroot(dic, IP3DBIDX_OBJECTS, index, root); + } + + return 0; +} Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.h 2006-12-27 08:08:26 UTC (rev 202) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.h 2006-12-27 11:40:38 UTC (rev 203) @@ -37,6 +37,9 @@ idx_t *idx_new(); void idx_finish(idx_t* idx); result_t idx_read(idx_t* idx, dic_t* dic, FILE *fpi); +result_t idx_write(idx_t* idx, dic_t* dic, FILE *fpo); result_t idx_dump(idx_t* idx, dic_t* dic, FILE *fpo); +result_t idx_construct(idx_t* idx, dic_t* dic, dat_t* dat); + #endif/*__IP3DB_IDX_H__*/ Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 08:08:26 UTC (rev 202) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 11:40:38 UTC (rev 203) @@ -127,6 +127,7 @@ { FILE *fp = 0; + /* Read db.dic */ fp = ucs2fopen(dicfn, "rb"); if (!fp) { ip3db_finish(db); @@ -135,11 +136,13 @@ fread_all(fp, &db->dic_buffer, &db->dic_size); fclose(fp); + /* Parse db.dic */ if (dic_serialize(db->dic, db->dic_buffer, 0) != 0) { ip3db_finish(db); return 1; } + /* Read db.dat */ fp = ucs2fopen(datfn, "rb"); if (!fp) { ip3db_finish(db); @@ -148,11 +151,13 @@ fread_all(fp, &db->dat_buffer, &db->dat_size); fclose(fp); + /* Parse db.dat */ if (dat_serialize(db->dat, db->dic, db->dat_buffer, 0) != 0) { ip3db_finish(db); return 1; } + /* Read and parse db.idx */ fp = ucs2fopen(idxfn, "rb"); if (!fp) { ip3db_finish(db); @@ -171,19 +176,13 @@ free(db->dat_buffer); db->dat_size = 0x00040000; - //db->dat_buffer = (uint8_t*)calloc(db->dat_size, sizeof(uint8_t)); - db->dat_buffer = (uint8_t*)malloc(db->dat_size); + db->dat_buffer = (uint8_t*)calloc(db->dat_size, sizeof(uint8_t)); if (dat_serialize(db->dat, db->dic, db->dat_buffer, 1) != 0) { ip3db_finish(db); return 1; } - if (dic_serialize(db->dic, db->dic_buffer, 1) != 0) { - ip3db_finish(db); - return 1; - } - fp = ucs2fopen(datfn, "wb"); if (!fp) { return 1; @@ -191,23 +190,22 @@ fwrite(db->dat_buffer, 1, db->dat_size, fp); fclose(fp); - /* - fp = ucs2fopen(dicfn, "rb"); + /* Construct db.idx and update db.dic. */ + idx_construct(db->idx, db->dic, db->dat); + + fp = ucs2fopen(idxfn, "wb"); if (!fp) { - ip3db_finish(db); return 1; } - fread_all(fp, &db->dic_buffer, &db->dic_size); + idx_write(db->idx, db->dic, fp); fclose(fp); - fp = ucs2fopen(idxfn, "rb"); - if (!fp) { + if (dic_serialize(db->dic, db->dic_buffer, 1) != 0) { ip3db_finish(db); return 1; } - fread_all(fp, &db->idx_buffer, &db->idx_size); + fwrite(db->dic_buffer, 1, db->dic_size, fp); fclose(fp); -*/ return 0; } @@ -229,11 +227,6 @@ { /* Construct Objects table in db.dat */ dat_construct(db->dat, db->dic, records, num_records); - - /* Construct db.idx */ - - /* Update db.dic */ - return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-27 14:23:48
|
Revision: 204 http://svn.sourceforge.net/pmplib/?rev=204&view=rev Author: nyaochi Date: 2006-12-27 06:23:47 -0800 (Wed, 27 Dec 2006) Log Message: ----------- A number of bug-fixes. The iriver E10 player can successfully navigate tracks in the database generated by EasyPMP now. The player cannot display the song information for some reason, and I'm finding out the reason. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 11:40:38 UTC (rev 203) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 14:23:47 UTC (rev 204) @@ -70,13 +70,20 @@ memset(entry, 0, sizeof(*entry)); } -static size_t dat_entry_serialize(dat_entry_t* entry, uint8_t* block, uint8_t* q, int is_storing) +static size_t dat_entry_serialize(dat_entry_t* entry, uint8_t* block, uint8_t* q, uint32_t start, int is_storing) { int i; uint8_t *p = block; + uint32_t offset; /* Serialize offset address of this entry. */ - q -= serialize_uint32be(q, &entry->offset, is_storing); + if (is_storing) { + offset = entry->offset - start; + q -= serialize_uint32be(q, &offset, is_storing); + } else { + q -= serialize_uint32be(q, &offset, is_storing); + entry->offset = offset + start; + } /* Serialize all fields in this entry. */ for (i = 0;i < entry->num_fields;++i) { @@ -161,17 +168,21 @@ dat_list_init(list); } -static size_t dat_list_serialize(dat_list_t* list, const dic_table_t* dic_list, uint8_t* buffer, int is_storing) +static size_t dat_list_serialize(dat_list_t* list, const dic_table_t* dic_list, uint8_t* buffer, uint32_t start, int is_storing) { uint32_t i; - uint8_t *p = buffer; - uint8_t *q = buffer + 0x00020000 - sizeof(uint32_t); + uint8_t *p = buffer + start; + uint8_t *q = buffer + start + 0x00020000 - sizeof(uint32_t); /* Serialize the header (with a dummy size for writing). */ - p += serialize_uint32be(p, &list->size, is_storing); - p += serialize_uint32be(p, &list->num_entries, is_storing); - p += serialize_uint32be(p, &list->unknown1, is_storing); - p += serialize_uint32be(p, &list->unknown2, is_storing); + if (!is_storing) { + p += serialize_uint32be(p, &list->size, is_storing); + p += serialize_uint32be(p, &list->num_entries, is_storing); + p += serialize_uint32be(p, &list->unknown1, is_storing); + p += serialize_uint32be(p, &list->unknown2, is_storing); + } else { + p += sizeof(uint32_t) * 4; + } /* Initialize fields when reading. */ if (!is_storing) { @@ -186,17 +197,19 @@ for (i = 0;i < list->num_entries;++i) { dat_entry_t* entry = &list->entries[i]; entry->offset = (uint32_t)(p - buffer); /* compute the current offset address */ - p += dat_entry_serialize(entry, p, q, is_storing); + p += dat_entry_serialize(entry, p, q, start, is_storing); q -= sizeof(uint32_t); } - /* Write the final size when writing. */ if (is_storing) { - uint32_t size = (uint32_t)(p - buffer); - serialize_uint32be(buffer, &size, is_storing); + list->size = (uint32_t)(p - (buffer + start)); + p = buffer + start; + p += serialize_uint32be(p, &list->size, is_storing); + p += serialize_uint32be(p, &list->num_entries, is_storing); + p += serialize_uint32be(p, &list->unknown1, is_storing); + p += serialize_uint32be(p, &list->unknown2, is_storing); } - - return (size_t)(p - buffer); + return (size_t)(list->size); } static void dat_list_dump(dat_list_t* list, const dic_table_t* dic_list, FILE *fp) @@ -237,8 +250,17 @@ size_t dat_serialize(dat_t* dat, const dic_t* dic, uint8_t* buffer, int is_storing) { - dat_list_serialize(&dat->objects, &dic->objects, buffer, is_storing); - dat_list_serialize(&dat->musics, &dic->music, buffer + 0x00020000, is_storing); + if (is_storing) { + int i; + ucs2char_t empty[] = {0}; + for (i = 0;i < dat->musics.num_entries;++i) { + dat_entry_t* entry = &dat->musics.entries[i]; + ip3db_variant_set_str(&entry->fields[IP3DBF_MUSIC_FILEPATH], empty); + ip3db_variant_set_str(&entry->fields[IP3DBF_MUSIC_FILENAME], empty); + } + } + dat_list_serialize(&dat->objects, &dic->objects, buffer, 0, is_storing); + dat_list_serialize(&dat->musics, &dic->music, buffer, 0x00020000, is_storing); return 0; } Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-27 11:40:38 UTC (rev 203) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-27 14:23:47 UTC (rev 204) @@ -284,10 +284,10 @@ return COMP(*x, *y); } -static int avl_insert_key(avl_t* avl, const void* key, int type, uint32_t* offset, uint32_t* root) +static int avl_insert_key(avl_t* avl, const ip3db_variant_t* key, int type, uint32_t* offset, uint32_t* root) { int ret = 0; - static avl_comp_t comp[] = {NULL, avl_comp_byte, avl_comp_word, avl_comp_dword, avl_comp_ucs2string}; + static avl_comp_t comp[] = {NULL, avl_comp_ucs2string, avl_comp_byte, avl_comp_word, avl_comp_dword}; uint32_t offset_prev = avl_current(avl); uint32_t offset_this = avlnode_new(avl); size_t size = 0; @@ -295,20 +295,23 @@ switch (type) { case IP3DBVT_BYTE: - size = sizeof(uint8_t); + offset_key = avl_allocate(avl, sizeof(uint8_t)); + *((uint8_t*)avlnode(avl, offset_key)) = key->value.byte; break; case IP3DBVT_WORD: - size = sizeof(uint16_t); + offset_key = avl_allocate(avl, sizeof(uint16_t)); + *((uint16_t*)avlnode(avl, offset_key)) = key->value.word; break; case IP3DBVT_DWORD: - size = sizeof(uint32_t); + offset_key = avl_allocate(avl, sizeof(uint32_t)); + *((uint32_t*)avlnode(avl, offset_key)) = key->value.dword; break; case IP3DBVT_STRING: - size = (ucs2len((const ucs2char_t*)key) + 1) * sizeof(ucs2char_t); + offset_key = avl_allocate(avl, sizeof(ucs2char_t) * (ucs2len(key->value.str) + 1)); + ucs2cpy((ucs2char_t*)avlnode(avl, offset_key), key->value.str); break; } - offset_key = avl_allocate(avl, (uint32_t)size); memcpy(avlnode(avl, offset_key), key, size); ret = avl_insert(avl, root, &offset_this, comp[type]); if (ret != -1) { @@ -441,47 +444,55 @@ } } -static void to_be_avltree(avl_t* avl, uint32_t offset, dic_table_t* dic_table, int index, int level) +static uint32_t to_be_avltree(avl_t* avl, uint32_t offset, dic_table_t* dic_table, int index, int level) { - avlnode_t* nbe = avlnode(avl, offset); - avlnode_t node = *nbe; + avlnode_t* node = avlnode(avl, offset); int field = dic_table->indices[index].fields[level]; int type = dic_table->fields[field].type; + uint32_t height = 1; - /* Convert the current node. */ - to_uint32be(&nbe->left); - to_uint32be(&nbe->right); - to_uint32be(&nbe->balance); - to_uint32be(&nbe->tail); - /* Descend to the left node. */ - if (node.left) { - to_be_avltree(avl, node.left, dic_table, index, level); + if (node->left) { + uint32_t new_height = to_be_avltree(avl, node->left, dic_table, index, level) + 1; + if (height < new_height) { + height = new_height; + } } + /* Descend to the right node. */ + if (node->right) { + uint32_t new_height = to_be_avltree(avl, node->right, dic_table, index, level) + 1; + if (height < new_height) { + height = new_height; + } + } + + /* Overwrite the balance field with the height of the current node. */ + node->balance = height; + /* Convert the key value. */ switch (type) { case IP3DBVT_BYTE: break; case IP3DBVT_WORD: - to_uint16be((uint16_t*)(nbe+1)); + to_uint16be((uint16_t*)(node+1)); break; case IP3DBVT_DWORD: - to_uint32be((uint32_t*)(nbe+1)); + to_uint32be((uint32_t*)(node+1)); break; case IP3DBVT_STRING: - to_ucs2be_string((ucs2char_t*)(nbe+1)); + to_ucs2be_string((ucs2char_t*)(node+1)); break; } /* Convert the sub AVL trees or tail. */ - if (node.tail) { + if (node->tail) { if (level+1 < IP3DBIDX_MAX_KEYLEVEL && dic_table->indices[index].fields[level+1] != -1) { /* Convert the AVL tree in the next level. */ - to_be_avltree(avl, node.tail, dic_table, index, level+1); + to_be_avltree(avl, node->tail, dic_table, index, level+1); } else { /* Convert the tail. */ - avltail_t* tbe = (avltail_t*)avlnode(avl, node.tail); + avltail_t* tbe = (avltail_t*)avlnode(avl, node->tail); avltail_t tail = *tbe; for (;;) { from_uint32be(&tbe->next); @@ -495,10 +506,12 @@ } } - /* Descend to the right node. */ - if (node.right) { - to_be_avltree(avl, node.right, dic_table, index, level); - } + /* Convert the current node. */ + to_uint32be(&node->left); + to_uint32be(&node->right); + to_uint32be(&node->balance); + to_uint32be(&node->tail); + return height; } static void fprinti(FILE *fp, int n) @@ -526,6 +539,8 @@ fprinti(fpo, indent); fprintf(fpo, " right: 0x%08X\n", node->right); fprinti(fpo, indent); + fprintf(fpo, " height: 0x%08X\n", node->balance); + fprinti(fpo, indent); fprintf(fpo, " tail: 0x%08X\n", node->tail); fprinti(fpo, indent); fprintf(fpo, " key: "); @@ -658,6 +673,8 @@ int i; idx_header_t* header = (idx_header_t*)idx->buffer; + header->size = idx->avl->offset; + /* Convert the byte order of the header from big endian to the native one. */ to_uint32be(&header->size); to_uint32be(&header->unknown1); @@ -718,7 +735,7 @@ uint32_t offset = 0; int field = dictbl->indices[index].fields[level]; int type = dictbl->fields[field].type; - int ret = avl_insert_key(idx->avl, &entry->fields[field].value, type, &offset, root); + int ret = avl_insert_key(idx->avl, &entry->fields[field], type, &offset, root); if (level+1 < IP3DBIDX_MAX_KEYLEVEL && dictbl->indices[index].fields[level+1] != -1) { avlnode_t* node = avlnode(idx->avl, offset); idx_insert_dat(idx, dictbl, &node->tail, entry, index, level+1); @@ -752,13 +769,13 @@ idx->avl->size = idx->max_size; for (index = 0;index < dic->music.num_indices;++index) { - uint32_t root = dic_get_idxroot(dic, IP3DBIDX_MUSIC, index); + uint32_t root = 0; idx_construct_index(idx, &dic->music, &dat->musics, &root, index); dic_set_idxroot(dic, IP3DBIDX_MUSIC, index, root); } for (index = 0;index < dic->objects.num_indices;++index) { - uint32_t root = dic_get_idxroot(dic, IP3DBIDX_OBJECTS, index); + uint32_t root = 0; idx_construct_index(idx, &dic->objects, &dat->objects, &root, index); dic_set_idxroot(dic, IP3DBIDX_OBJECTS, index, root); } Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 11:40:38 UTC (rev 203) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 14:23:47 UTC (rev 204) @@ -40,6 +40,9 @@ { memset(var, 0, sizeof(*var)); var->type = type; + if (var->type == IP3DBVT_STRING) { + var->value.str = mbsdupucs2(""); + } } void ip3db_variant_finish(ip3db_variant_t* var) @@ -204,6 +207,11 @@ ip3db_finish(db); return 1; } + + fp = ucs2fopen(dicfn, "wb"); + if (!fp) { + return 1; + } fwrite(db->dic_buffer, 1, db->dic_size, fp); fclose(fp); Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-27 11:40:38 UTC (rev 203) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-27 14:23:47 UTC (rev 204) @@ -171,6 +171,7 @@ void ip3db_init(ip3db_t* db); void ip3db_finish(ip3db_t* db); result_t ip3db_read(ip3db_t* db, const ucs2char_t* datfn, const ucs2char_t* dicfn, const ucs2char_t* idxfn); +result_t ip3db_write(ip3db_t* db, const ucs2char_t* datfn, const ucs2char_t* dicfn, const ucs2char_t* idxfn); result_t ip3db_dump(ip3db_t* db, FILE *fpo); void ip3db_record_init(ip3db_t* db, ip3db_music_record_t* record); Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-27 11:40:38 UTC (rev 203) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-27 14:23:47 UTC (rev 204) @@ -505,6 +505,16 @@ ); } +static ucs2char_t* _filepath_removeslash(ucs2char_t* path) +{ + size_t length = ucs2len(path)-1; + while (length >= 0 && path[length] == PATHCHAR) { + path[length] = 0; + length--; + } + return (path + length); +} + static result_t pmpdb_set(pmpdb_t* pmpdb, const pmp_record_t* records, uint32_t num_records) { int i; @@ -515,7 +525,7 @@ ip3db_music_record_t* array = (ip3db_music_record_t*)malloc(sizeof(ip3db_music_record_t) * num_records); ucs2cpy(path_to_root, pmpi->env.path_to_root); - filepath_removeslash(path_to_root); + _filepath_removeslash(path_to_root); for (i = 0;i < num_records;++i) { const pmp_record_t* src = &records[i]; @@ -527,6 +537,16 @@ filepath_addslash(dst[IP3DBF_MUSIC_FILEPATH].value.str); filepath_encode(dst[IP3DBF_MUSIC_FILEPATH].value.str); ip3db_variant_set_str(&dst[IP3DBF_MUSIC_FILENAME], filepath_skippath(src->filename)); + ip3db_variant_set_str(&dst[IP3DBF_MUSIC_ARTIST], src->artist); + ip3db_variant_set_str(&dst[IP3DBF_MUSIC_ALBUM], src->album); + ip3db_variant_set_str(&dst[IP3DBF_MUSIC_GENRE], src->genre); + ip3db_variant_set_str(&dst[IP3DBF_MUSIC_TITLE], src->title); + ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_DURATION], src->duration); + ip3db_variant_set_word(&dst[IP3DBF_MUSIC_RATING], (uint16_t)src->rating); + ip3db_variant_set_word(&dst[IP3DBF_MUSIC_FILEFORMAT], 3); + ip3db_variant_set_word(&dst[IP3DBF_MUSIC_TRACKNUMBER], (uint16_t)src->track_number); + ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_BITRATE], src->bitrate); + ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_UID], (uint32_t)i+1); } ip3db_set(&pmpdbi->ip3db, array, num_records); free(array); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-27 14:50:16
|
Revision: 205 http://svn.sourceforge.net/pmplib/?rev=205&view=rev Author: nyaochi Date: 2006-12-27 06:50:16 -0800 (Wed, 27 Dec 2006) Log Message: ----------- Convert back-slash characters to slash characters in path names in the database. Hooray! I did it. The player worked fine with the database now. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 14:23:47 UTC (rev 204) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 14:50:16 UTC (rev 205) @@ -39,7 +39,6 @@ #include <stdlib.h> #include <memory.h> #include <ucs2char.h> -#include <filepath.h> #include "serialize.h" #include "util.h" @@ -346,7 +345,13 @@ return &dc->elems[i]; } +static const ucs2char_t* skip_one_directory(const ucs2char_t* path) +{ + ucs2char_t* p = ucs2chr(path, '/'); + return p ? p+1 : NULL; +} + void dat_construct(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records) { int i, j; @@ -354,7 +359,7 @@ uint32_t uid = 0; static const uint32_t uid_root = 0xFFFFFFFF; static const ucs2char_t ucs2cs_object_root[] = {'/','a','/',0}; - static const ucs2char_t ucs2cs_root[] = {PATHCHAR, 0}; + static const ucs2char_t ucs2cs_root[] = {'/', 0}; dat_list_t* dato = &dat->objects; dat_list_t* datm = &dat->musics; dircache_t dc; @@ -394,7 +399,7 @@ while (p && *p) { ucs2char_t tmp[MAX_PATH]; - const ucs2char_t* q = filepath_skip_one_directory(p); + const ucs2char_t* q = skip_one_directory(p); uid = dato->num_entries; ucs2ncpy(tmp, p, q-p); Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-27 14:23:47 UTC (rev 204) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-27 14:50:16 UTC (rev 205) @@ -515,6 +515,17 @@ return (path + length); } +static int _filepath_slash(ucs2char_t* path) +{ + while (*path) { + if (*path == 0x005C) { + *path = 0x002F; + } + path++; + } + return 0; +} + static result_t pmpdb_set(pmpdb_t* pmpdb, const pmp_record_t* records, uint32_t num_records) { int i; @@ -535,7 +546,7 @@ ip3db_variant_set_str(&dst[IP3DBF_MUSIC_FILEPATH], src->filename + ucs2len(path_to_root)); filepath_remove_filespec(dst[IP3DBF_MUSIC_FILEPATH].value.str); filepath_addslash(dst[IP3DBF_MUSIC_FILEPATH].value.str); - filepath_encode(dst[IP3DBF_MUSIC_FILEPATH].value.str); + _filepath_slash(dst[IP3DBF_MUSIC_FILEPATH].value.str); ip3db_variant_set_str(&dst[IP3DBF_MUSIC_FILENAME], filepath_skippath(src->filename)); ip3db_variant_set_str(&dst[IP3DBF_MUSIC_ARTIST], src->artist); ip3db_variant_set_str(&dst[IP3DBF_MUSIC_ALBUM], src->album); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-27 17:07:29
|
Revision: 207 http://svn.sourceforge.net/pmplib/?rev=207&view=rev Author: nyaochi Date: 2006-12-27 09:07:29 -0800 (Wed, 27 Dec 2006) Log Message: ----------- Source code clean-up. The ip3db_t structure does not hold the entire memory block for db.dat any more. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/dat.h trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 16:38:53 UTC (rev 206) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 17:07:29 UTC (rev 207) @@ -247,7 +247,7 @@ free(dat); } -size_t dat_serialize(dat_t* dat, const dic_t* dic, uint8_t* buffer, int is_storing) +static size_t dat_serialize(dat_t* dat, const dic_t* dic, uint8_t* buffer, int is_storing) { if (is_storing) { int i; @@ -263,6 +263,48 @@ return 0; } +int dat_read(dat_t* dat, const dic_t* dic, FILE *fpi) +{ + long buffer_size = 0; + uint8_t* buffer = NULL; + + fread_all(fpi, &buffer, &buffer_size); + if (!buffer) { + return 1; + } + + if (dat_serialize(dat, dic, buffer, 0) != 0) { + free(buffer); + return 1; + } + + free(buffer); + return 0; +} + +int dat_write(dat_t* dat, const dic_t* dic, FILE *fpo) +{ + long buffer_size = 0x00040000; + uint8_t* buffer = (uint8_t*)calloc(buffer_size, sizeof(uint8_t)); + + if (!buffer) { + return 1; + } + + if (dat_serialize(dat, dic, buffer, 1) != 0) { + free(buffer); + return 1; + } + + if (fwrite(buffer, 1, buffer_size, fpo) != buffer_size) { + free(buffer); + return 1; + } + + free(buffer); + return 0; +} + void dat_dump(dat_t* dat, const dic_t* dic, FILE *fp) { fprintf(fp, "===== db.dat =====\n"); Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-27 16:38:53 UTC (rev 206) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-27 17:07:29 UTC (rev 207) @@ -46,9 +46,9 @@ dat_t* dat_new(); void dat_finish(dat_t* dat); -size_t dat_serialize(dat_t* dat, const dic_t* dic, uint8_t* buffer, int is_storing); +int dat_read(dat_t* dat, const dic_t* dic, FILE *fpi); +int dat_write(dat_t* dat, const dic_t* dic, FILE *fpo); void dat_dump(dat_t* dat, const dic_t* dic, FILE *fp); - void dat_construct(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records); #endif/*__IP3DB_DAT_H__*/ Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 16:38:53 UTC (rev 206) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 17:07:29 UTC (rev 207) @@ -95,11 +95,7 @@ break; case IP3DBVT_STRING: ucs2free(dst->value.str); - if (src->value.str) { - dst->value.str = ucs2dup(src->value.str); - } else { - dst->value.str = 0; - } + dst->value.str = src->value.str ? ucs2dup(src->value.str) : 0; break; } } @@ -108,15 +104,19 @@ { uint8_t *dic_template = NULL; + /* Construct db->dat, db->dic, and db->idx */ memset(db, 0, sizeof(*db)); db->dat = dat_new(); db->dic = dic_new(); db->idx = idx_new(); + /* Initialize db->dic, which rules everything in a database. */ dic_template = dic_get_template(&db->dic_size); db->dic_buffer = (uint8_t*)malloc(db->dic_size); - memcpy(db->dic_buffer, dic_template, db->dic_size); - dic_serialize(db->dic, db->dic_buffer, 0); + if (db->dic_buffer) { + memcpy(db->dic_buffer, dic_template, db->dic_size); + dic_serialize(db->dic, db->dic_buffer, 0); + } } void ip3db_finish(ip3db_t* db) @@ -124,9 +124,8 @@ dic_finish(db->dic); dat_finish(db->dat); idx_finish(db->idx); - free(db->dat_buffer); free(db->dic_buffer); - ip3db_init(db); + memset(db, 0, sizeof(*db)); } result_t ip3db_read(ip3db_t* db, const ucs2char_t* datfn, const ucs2char_t* dicfn, const ucs2char_t* idxfn) @@ -154,15 +153,9 @@ ip3db_finish(db); return 1; } - fread_all(fp, &db->dat_buffer, &db->dat_size); + dat_read(db->dat, db->dic, fp); fclose(fp); - /* Parse db.dat */ - if (dat_serialize(db->dat, db->dic, db->dat_buffer, 0) != 0) { - ip3db_finish(db); - return 1; - } - /* Read and parse db.idx */ fp = ucs2fopen(idxfn, "rb"); if (!fp) { @@ -179,21 +172,12 @@ { FILE *fp = 0; - free(db->dat_buffer); - - db->dat_size = 0x00040000; - db->dat_buffer = (uint8_t*)calloc(db->dat_size, sizeof(uint8_t)); - - if (dat_serialize(db->dat, db->dic, db->dat_buffer, 1) != 0) { - ip3db_finish(db); - return 1; - } - + /* Write db.dat. This will allocate offset values of the records. */ fp = ucs2fopen(datfn, "wb"); if (!fp) { return 1; } - fwrite(db->dat_buffer, 1, db->dat_size, fp); + dat_write(db->dat, db->dic, fp); fclose(fp); /* Construct db.idx and update db.dic. */ Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-27 16:38:53 UTC (rev 206) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-27 17:07:29 UTC (rev 207) @@ -92,6 +92,9 @@ */ typedef ip3db_variant_t ip3db_music_record_t[IP3DBF_MUSIC_LAST]; +/** + * Fields in a object record. + */ enum { IP3DBF_OBJECTS_NONE = -1, IP3DBF_OBJECTS_BEGIN = 0, @@ -109,11 +112,17 @@ IP3DBF_OBJECTS_LAST, }; +/** + * Fields chunks in db.dat. + */ enum { IP3DBIDX_MUSIC = 0, IP3DBIDX_OBJECTS, }; +/** + * Indices for the music chunk. + */ enum { IP3DBIDX_MUSIC_NONE = -1, IP3DBIDX_MUSIC_BEGIN = 0, @@ -132,6 +141,9 @@ IP3DBIDX_MUSIC_LAST, }; +/** + * Indices for the object chunk. + */ enum { IP3DBIDX_OBJECT_NONE = -1, IP3DBIDX_OBJECT_BEGIN = 0, @@ -149,8 +161,6 @@ struct tag_idx_t; typedef struct tag_idx_t idx_t; typedef struct { - uint8_t* dat_buffer; - long dat_size; uint8_t* dic_buffer; long dic_size; @@ -172,9 +182,9 @@ void ip3db_finish(ip3db_t* db); result_t ip3db_read(ip3db_t* db, const ucs2char_t* datfn, const ucs2char_t* dicfn, const ucs2char_t* idxfn); result_t ip3db_write(ip3db_t* db, const ucs2char_t* datfn, const ucs2char_t* dicfn, const ucs2char_t* idxfn); +result_t ip3db_set(ip3db_t* db, const ip3db_music_record_t* records, int num_records); result_t ip3db_dump(ip3db_t* db, FILE *fpo); void ip3db_record_init(ip3db_t* db, ip3db_music_record_t* record); -result_t ip3db_set(ip3db_t* db, const ip3db_music_record_t* records, int num_records); #endif /*_IP3DB_IP3DB_H__*/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-27 17:24:51
|
Revision: 208 http://svn.sourceforge.net/pmplib/?rev=208&view=rev Author: nyaochi Date: 2006-12-27 09:24:52 -0800 (Wed, 27 Dec 2006) Log Message: ----------- Source code clean-up: make dic_t manage the buffer for db.dic. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dic.c trunk/pmplib/lib/pmp_iriverplus3/dic.h trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-27 17:07:29 UTC (rev 207) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-27 17:24:52 UTC (rev 208) @@ -64,6 +64,7 @@ {0, 0x0ACE, {IP3DBF_OBJECTS_FILETYPE, IP3DBF_OBJECTS_PARENTUID, IP3DBF_OBJECTS_PROPERTIES}}, }; +static int dic_serialize(dic_t* dic, uint8_t* buffer, int is_storing); static void dic_field_init(dic_field_t* entry) { @@ -129,6 +130,7 @@ dic_t* dic_new() { + uint8_t* dic_template = NULL; dic_t* dic = (dic_t*)malloc(sizeof(dic_t)); if (dic) { dic_table_init(&dic->music); @@ -141,6 +143,14 @@ dic->objects.fields = (dic_field_t*)calloc(dic->objects.num_fields, sizeof(dic_field_t)); dic->objects.num_indices = sizeof(objects_indices) / sizeof(objects_indices[0]); dic->objects.indices = objects_indices; + + /* Read the database description, which rules everything in a database. */ + dic_template = dic_get_template(&dic->size); + dic->buffer = (uint8_t*)malloc(dic->size); + if (dic->buffer) { + memcpy(dic->buffer, dic_template, dic->size); + dic_serialize(dic, dic->buffer, 0); + } } return dic; } @@ -150,12 +160,38 @@ if (dic) { dic_table_finish(&dic->music); dic_table_finish(&dic->objects); + free(dic->buffer); free(dic); } } -int dic_serialize(dic_t* dic, uint8_t* buffer, int is_storing) +int dic_read(dic_t* dic, FILE *fpi) { + free(dic->buffer); + dic->size = 0; + + fread_all(fpi, &dic->buffer, &dic->size); + + /* Parse db.dic */ + if (dic_serialize(dic, dic->buffer, 0) != 0) { + return 1; + } + return 0; +} + +int dic_write(dic_t* dic, FILE *fpo) +{ + if (dic_serialize(dic, dic->buffer, 1) != 0) { + return 1; + } + + fwrite(dic->buffer, 1, dic->size, fpo); + + return 0; +} + +static int dic_serialize(dic_t* dic, uint8_t* buffer, int is_storing) +{ int i; uint32_t next = 0; Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-27 17:07:29 UTC (rev 207) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-27 17:24:52 UTC (rev 208) @@ -47,12 +47,16 @@ struct tag_dic_t { dic_table_t music; dic_table_t objects; + + uint8_t* buffer; + long size; }; typedef struct tag_dic_t dic_t; dic_t* dic_new(); void dic_finish(dic_t* dic); -int dic_serialize(dic_t* dic, uint8_t* buffer, int is_storing); +int dic_read(dic_t* dic, FILE *fpi); +int dic_write(dic_t* dic, FILE *fpo); void dic_dump(dic_t* dic, FILE *fp); uint32_t dic_get_idxroot(dic_t* dic, int table, int index); void dic_set_idxroot(dic_t* dic, int table, int index, uint32_t root); Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 17:07:29 UTC (rev 207) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 17:24:52 UTC (rev 208) @@ -102,21 +102,11 @@ void ip3db_init(ip3db_t* db) { - uint8_t *dic_template = NULL; - /* Construct db->dat, db->dic, and db->idx */ memset(db, 0, sizeof(*db)); db->dat = dat_new(); db->dic = dic_new(); db->idx = idx_new(); - - /* Initialize db->dic, which rules everything in a database. */ - dic_template = dic_get_template(&db->dic_size); - db->dic_buffer = (uint8_t*)malloc(db->dic_size); - if (db->dic_buffer) { - memcpy(db->dic_buffer, dic_template, db->dic_size); - dic_serialize(db->dic, db->dic_buffer, 0); - } } void ip3db_finish(ip3db_t* db) @@ -124,7 +114,6 @@ dic_finish(db->dic); dat_finish(db->dat); idx_finish(db->idx); - free(db->dic_buffer); memset(db, 0, sizeof(*db)); } @@ -138,15 +127,9 @@ ip3db_finish(db); return 1; } - fread_all(fp, &db->dic_buffer, &db->dic_size); + dic_read(db->dic, fp); fclose(fp); - /* Parse db.dic */ - if (dic_serialize(db->dic, db->dic_buffer, 0) != 0) { - ip3db_finish(db); - return 1; - } - /* Read db.dat */ fp = ucs2fopen(datfn, "rb"); if (!fp) { @@ -156,7 +139,7 @@ dat_read(db->dat, db->dic, fp); fclose(fp); - /* Read and parse db.idx */ + /* Read db.idx */ fp = ucs2fopen(idxfn, "rb"); if (!fp) { ip3db_finish(db); @@ -190,16 +173,11 @@ idx_write(db->idx, db->dic, fp); fclose(fp); - if (dic_serialize(db->dic, db->dic_buffer, 1) != 0) { - ip3db_finish(db); - return 1; - } - fp = ucs2fopen(dicfn, "wb"); if (!fp) { return 1; } - fwrite(db->dic_buffer, 1, db->dic_size, fp); + dic_write(db->dic, fp); fclose(fp); return 0; Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-27 17:07:29 UTC (rev 207) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-27 17:24:52 UTC (rev 208) @@ -161,13 +161,9 @@ struct tag_idx_t; typedef struct tag_idx_t idx_t; typedef struct { - uint8_t* dic_buffer; - long dic_size; - dat_t* dat; dic_t* dic; idx_t* idx; - } ip3db_t; void ip3db_variant_init(ip3db_variant_t* var, int type); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-27 19:04:23
|
Revision: 209 http://svn.sourceforge.net/pmplib/?rev=209&view=rev Author: nyaochi Date: 2006-12-27 11:04:23 -0800 (Wed, 27 Dec 2006) Log Message: ----------- More source code clean-up. Added comments in dat.c Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/dat.h trunk/pmplib/lib/pmp_iriverplus3/ip3db.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 17:24:52 UTC (rev 208) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-27 19:04:23 UTC (rev 209) @@ -75,7 +75,11 @@ uint8_t *p = block; uint32_t offset; - /* Serialize offset address of this entry. */ + /* + * Serialize offset address of this entry. + * entry->offset: The offset address in the whole db.dat buffer (e.g., 0x00020123) + * offset (written in db.dat): The one within the chunk (e.g., 0x00000123) + */ if (is_storing) { offset = entry->offset - start; q -= serialize_uint32be(q, &offset, is_storing); @@ -151,12 +155,6 @@ memset(list, 0, sizeof(*list)); } -static dat_entry_t *dat_list_expand(dat_list_t* list) -{ - list->entries = (dat_entry_t*)realloc(list->entries, sizeof(dat_entry_t) * (list->num_entries+1)); - return &list->entries[list->num_entries++]; -} - static void dat_list_finish(dat_list_t* list) { uint32_t i; @@ -164,28 +162,35 @@ dat_entry_finish(&list->entries[i]); } free(list->entries); - dat_list_init(list); + memset(list, 0, sizeof(*list)); } +static dat_entry_t *dat_list_expand(dat_list_t* list) +{ + list->entries = (dat_entry_t*)realloc(list->entries, sizeof(dat_entry_t) * (list->num_entries+1)); + return &list->entries[list->num_entries++]; +} + static size_t dat_list_serialize(dat_list_t* list, const dic_table_t* dic_list, uint8_t* buffer, uint32_t start, int is_storing) { uint32_t i; uint8_t *p = buffer + start; uint8_t *q = buffer + start + 0x00020000 - sizeof(uint32_t); - /* Serialize the header (with a dummy size for writing). */ if (!is_storing) { + /* Read the header. */ p += serialize_uint32be(p, &list->size, is_storing); p += serialize_uint32be(p, &list->num_entries, is_storing); p += serialize_uint32be(p, &list->unknown1, is_storing); p += serialize_uint32be(p, &list->unknown2, is_storing); } else { + /* Skip the header for now when writing. */ p += sizeof(uint32_t) * 4; } - /* Initialize fields when reading. */ + /* Initialize fields according to db.dic when reading. */ if (!is_storing) { - free(list->entries); + dat_list_finish(list); list->entries = (dat_entry_t*)calloc(list->num_entries, sizeof(dat_entry_t)); for (i = 0;i < list->num_entries;++i) { dat_entry_init(&list->entries[i], dic_list); @@ -201,6 +206,7 @@ } if (is_storing) { + /* Compute the block size and write the header. */ list->size = (uint32_t)(p - (buffer + start)); p = buffer + start; p += serialize_uint32be(p, &list->size, is_storing); @@ -208,6 +214,7 @@ p += serialize_uint32be(p, &list->unknown1, is_storing); p += serialize_uint32be(p, &list->unknown2, is_storing); } + return (size_t)(list->size); } @@ -250,9 +257,12 @@ static size_t dat_serialize(dat_t* dat, const dic_t* dic, uint8_t* buffer, int is_storing) { if (is_storing) { + /* For writing a music chunk only. + * Empty filepath and filename fields as iriver plus 3 does. + */ int i; - ucs2char_t empty[] = {0}; for (i = 0;i < dat->musics.num_entries;++i) { + static const ucs2char_t empty[] = {0}; dat_entry_t* entry = &dat->musics.entries[i]; ip3db_variant_set_str(&entry->fields[IP3DBF_MUSIC_FILEPATH], empty); ip3db_variant_set_str(&entry->fields[IP3DBF_MUSIC_FILENAME], empty); @@ -316,24 +326,7 @@ fprintf(fp, "}\n"); } -typedef struct { - const ip3db_music_record_t* base; - int index; -} ip3db_sort_index_t; -static int comp_pathname(const void *__x, const void *__y) -{ - const ip3db_sort_index_t* _x = (const ip3db_sort_index_t*)__x; - const ip3db_sort_index_t* _y = (const ip3db_sort_index_t*)__y; - const ip3db_variant_t* x = _x->base[_x->index]; - const ip3db_variant_t* y = _y->base[_y->index]; - int ret = ucs2cmp(x[IP3DBF_MUSIC_FILEPATH].value.str, y[IP3DBF_MUSIC_FILEPATH].value.str); - if (ret == 0) { - return ucs2cmp(x[IP3DBF_MUSIC_FILENAME].value.str, y[IP3DBF_MUSIC_FILENAME].value.str); - } else { - return ret; - } -} typedef struct { ucs2char_t* path; @@ -392,15 +385,62 @@ return &dc->elems[i]; } + + +typedef struct { + const ip3db_music_record_t* base; + int index; +} sort_index_t; + +static int comp_pathname(const void *__x, const void *__y) +{ + const sort_index_t* _x = (const sort_index_t*)__x; + const sort_index_t* _y = (const sort_index_t*)__y; + const ip3db_variant_t* x = _x->base[_x->index]; + const ip3db_variant_t* y = _y->base[_y->index]; + int ret = ucs2cmp(x[IP3DBF_MUSIC_FILEPATH].value.str, y[IP3DBF_MUSIC_FILEPATH].value.str); + if (ret == 0) { + return ucs2cmp(x[IP3DBF_MUSIC_FILENAME].value.str, y[IP3DBF_MUSIC_FILENAME].value.str); + } else { + return ret; + } +} + + + static const ucs2char_t* skip_one_directory(const ucs2char_t* path) { ucs2char_t* p = ucs2chr(path, '/'); return p ? p+1 : NULL; } +void dat_set(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records) +{ + /* Procedure: + * 1) Construct the object chunk and attach music records with Object UIDs. + * Because the object chunk stores a tree structure of path names, we need to + * split a path name to elements and allocate an Object UID to each element. + * For example, the path name "/Music/Beatles/Love/01_love.ogg" will generate + * five objects each of which links to the object of the parent directory: + * - UID=0xFFFFFFFF: "/a/" (root directory; FileType = 0) + * - UID=1 : "Music/" (FileType = 1) + * - UID=2 : "Beatles/" (FileType = 1) + * - UID=3 : "Love/" (FileType = 1) + * - UID=4 : "01_love.ogg" (FileType = 2) + * In order to convert a list of path names to the tree structure, this + * implementation sorts the path names in alphabetical order and finds new + * path elements by using a directory queue (dircache_t). + * + * 3) Attach Object UIDs for file names (FileType = 2) to music records. + * These UIDs are stored in records in the music chunk so that the player + * can refer to the path/file name of a music track quickly. + * + * 4) Construct the music chunk by basically duplicating the records. + * + * Now the content of db.dat is ready. Note that the path character in db.dat + * is not '\\' but '/'. + */ -void dat_construct(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records) -{ int i, j; dat_entry_t* entry; uint32_t uid = 0; @@ -409,8 +449,8 @@ static const ucs2char_t ucs2cs_root[] = {'/', 0}; dat_list_t* dato = &dat->objects; dat_list_t* datm = &dat->musics; + sort_index_t *si = (sort_index_t*)malloc(sizeof(sort_index_t) * num_records); dircache_t dc; - ip3db_sort_index_t *si = (ip3db_sort_index_t*)malloc(sizeof(ip3db_sort_index_t) * num_records); dircache_init(&dc); @@ -427,31 +467,42 @@ /* Register the root node to the directory cache. */ dircache_push(&dc, ucs2cs_root, uid_root); + /* Sort the records in alphabetical order of their path names. */ for (i = 0;i < num_records;++i) { si[i].base = records; si[i].index = i; } qsort(si, num_records, sizeof(si[0]), comp_pathname); + /* Loop for the records. */ for (i = 0;i < num_records;++i) { + /* + * Split a path name into two parts: a prefix that have already been + * registered in the Object table: and a postfix that is being registered + * as Object records. + */ const ip3db_variant_t* record = records[si[i].index]; const ucs2char_t* path = record[IP3DBF_MUSIC_FILEPATH].value.str; const ucs2char_t* file = record[IP3DBF_MUSIC_FILENAME].value.str; int i = dircache_findprefix(&dc, path); const dircache_element_t* com = dircache_get(&dc, i); - const ucs2char_t* p = path + ucs2len(com->path); - uint32_t puid = com->uid; + const ucs2char_t* p = path + ucs2len(com->path); /* the prefix */ + uint32_t puid = com->uid; /* the UID of the parent directory of the postfix */ + /* Discard directory portions that do not share a prefix with the target. */ dircache_pop(&dc, i); + /* Create objects one by one for the directory portions in the postfix. */ while (p && *p) { ucs2char_t tmp[MAX_PATH]; const ucs2char_t* q = skip_one_directory(p); uid = dato->num_entries; + /* A directory element (e.g., "Beatles/") */ ucs2ncpy(tmp, p, q-p); tmp[q-p] = 0; + /* Create a new object. */ entry = dat_list_expand(dato); dat_entry_init(entry, &dic->objects); ip3db_variant_set_dword(&entry->fields[IP3DBF_OBJECTS_UID], uid); @@ -459,11 +510,15 @@ ip3db_variant_set_word(&entry->fields[IP3DBF_OBJECTS_FILETYPE], 1); ip3db_variant_set_str(&entry->fields[IP3DBF_OBJECTS_OBJECTNAME], tmp); + /* Register the fullpath (e.g., "/Music/eatles/" in the dircache. */ ucs2ncpy(tmp, path, q-path); tmp[q-path] = 0; dircache_push(&dc, tmp, uid); + /* Store the current UID for children. */ puid = uid; + + /* Move to the next portion. */ p = q; } Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-27 17:24:52 UTC (rev 208) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-27 19:04:23 UTC (rev 209) @@ -49,6 +49,6 @@ int dat_read(dat_t* dat, const dic_t* dic, FILE *fpi); int dat_write(dat_t* dat, const dic_t* dic, FILE *fpo); void dat_dump(dat_t* dat, const dic_t* dic, FILE *fp); -void dat_construct(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records); +void dat_set(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records); #endif/*__IP3DB_DAT_H__*/ Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 17:24:52 UTC (rev 208) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 19:04:23 UTC (rev 209) @@ -198,8 +198,8 @@ result_t ip3db_set(ip3db_t* db, const ip3db_music_record_t* records, int num_records) { - /* Construct Objects table in db.dat */ - dat_construct(db->dat, db->dic, records, num_records); + /* Set music records to dat_t. */ + dat_set(db->dat, db->dic, records, num_records); return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-28 03:20:31
|
Revision: 212 http://svn.sourceforge.net/pmplib/?rev=212&view=rev Author: nyaochi Date: 2006-12-27 19:20:31 -0800 (Wed, 27 Dec 2006) Log Message: ----------- Add more comments. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dic.c trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-27 19:22:33 UTC (rev 211) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-28 03:20:31 UTC (rev 212) @@ -23,7 +23,7 @@ /* Some important findings from db.dic: -- This file seems to define field names/types in a database. +- This file defines field names/types in a database. - This file stores offset addresses of root nodes in db.idx. */ Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-27 19:22:33 UTC (rev 211) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 03:20:31 UTC (rev 212) @@ -23,12 +23,19 @@ /* Brief summary of db.idx structure: -- This file seems to have 12-bytes header +- This file has 12-bytes header - Indices consist of multiple binary search trees -- The offset addresses to the root nodes are specified in db.dic +- The offset addresses to the root nodes are described in db.dic Implementation note: -- The AVL trees are +- The byte order of values (such as offset address, key values, etc) + in AVL trees depends on the CPU architecture on which this code runs. + Since values in db.idx are written in big-endian, the functions + from_be_avltree() and to_be_avltree() convert the byte order from/to + big endian to the native byte-order on memory. +- The balance field of an AVL node stores values -1, 0, or 1 although + the field stores the height of a node in db.idx. This conversion + will take place in the function to_be_avltree(). */ #ifdef HAVE_CONFIG_H Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-27 19:22:33 UTC (rev 211) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-28 03:20:31 UTC (rev 212) @@ -121,7 +121,10 @@ { FILE *fp = 0; - /* Read db.dic */ + /* + * Read db.dic first since this file describes the structure of a database + * (e.g., field type and the offset values to the root nodes in db.idx). + */ fp = ucs2fopen(dicfn, "rb"); if (!fp) { ip3db_finish(db); @@ -155,7 +158,11 @@ { FILE *fp = 0; - /* Write db.dat. This will allocate offset values of the records. */ + /* + * Write db.dat. The function dat_write() also stores offset addresses + * (db->dat->objects.entries[i].offset and db->dat->music.entries[i].offset) + * where records are stored in the file. + */ fp = ucs2fopen(datfn, "wb"); if (!fp) { return 1; @@ -163,9 +170,18 @@ dat_write(db->dat, db->dic, fp); fclose(fp); - /* Construct db.idx and update db.dic. */ + /* + * Construct binary search trees from records in db->dat. The root offset + * of each search tree will be stored in db->dic. + */ idx_construct(db->idx, db->dic, db->dat); + /* + * Write db.idx. The function idx_write() converts values in the search trees + * from native byte-order to big endian. The byte-order conversion will take + * place in memory. Therefore, do not use db->idx after calling idx_write() + * function. + */ fp = ucs2fopen(idxfn, "wb"); if (!fp) { return 1; @@ -173,6 +189,7 @@ idx_write(db->idx, db->dic, fp); fclose(fp); + /* Write db.dic. */ fp = ucs2fopen(dicfn, "wb"); if (!fp) { return 1; @@ -198,7 +215,7 @@ result_t ip3db_set(ip3db_t* db, const ip3db_music_record_t* records, int num_records) { - /* Set music records to dat_t. */ + /* Construct records in db->dat from the records. */ dat_set(db->dat, db->dic, records, num_records); return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-28 05:46:52
|
Revision: 216 http://svn.sourceforge.net/pmplib/?rev=216&view=rev Author: nyaochi Date: 2006-12-27 21:46:51 -0800 (Wed, 27 Dec 2006) Log Message: ----------- - Fixed a bug in dircache. - Set proper FileFormat IDs for MP3, OggVorbis, and WMA. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 05:09:07 UTC (rev 215) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 05:46:51 UTC (rev 216) @@ -350,6 +350,15 @@ memset(dc, 0, sizeof(*dc)); } +static void dircache_finish(dircache_t* dc) +{ + int i; + for (i = 0;i < dc->max_elems;++i) { + ucs2free(dc->elems[i].path); + } + free(dc->elems); +} + static void dircache_push(dircache_t* dc, const ucs2char_t* path, uint32_t uid) { dircache_element_t* elem = NULL; @@ -368,11 +377,12 @@ static void dircache_pop(dircache_t* dc, int i) { - ++i; + int n = ++i; for (;i < dc->num_elems;++i) { ucs2free(dc->elems[i].path); memset(&dc->elems[i], 0, sizeof(dc->elems[0])); } + dc->num_elems = n; } static int dircache_findprefix(dircache_t* dc, const ucs2char_t* path) @@ -490,13 +500,13 @@ const ip3db_variant_t* record = records[si[i].index]; const ucs2char_t* path = record[IP3DBF_MUSIC_FILEPATH].value.str; const ucs2char_t* file = record[IP3DBF_MUSIC_FILENAME].value.str; - int i = dircache_findprefix(&dc, path); - const dircache_element_t* com = dircache_get(&dc, i); + int k = dircache_findprefix(&dc, path); + const dircache_element_t* com = dircache_get(&dc, k); const ucs2char_t* p = path + ucs2len(com->path); /* the prefix */ uint32_t puid = com->uid; /* the UID of the parent directory of the postfix */ /* Discard directory portions that do not share a prefix with the target. */ - dircache_pop(&dc, i); + dircache_pop(&dc, k); /* Create objects one by one for the directory portions in the postfix. */ while (p && *p) { @@ -545,4 +555,6 @@ } ip3db_variant_set_dword(&entry->fields[IP3DBF_MUSIC_UID], uid); } + + dircache_finish(&dc); } Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-28 05:09:07 UTC (rev 215) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-28 05:46:51 UTC (rev 216) @@ -554,10 +554,21 @@ ip3db_variant_set_str(&dst[IP3DBF_MUSIC_TITLE], src->title); ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_DURATION], src->duration); ip3db_variant_set_word(&dst[IP3DBF_MUSIC_RATING], (uint16_t)src->rating); - ip3db_variant_set_word(&dst[IP3DBF_MUSIC_FILEFORMAT], 3); + switch (src->codec) { + case PMPCODEC_MPEGLAYER3: + ip3db_variant_set_word(&dst[IP3DBF_MUSIC_FILEFORMAT], 0); + break; + case PMPCODEC_VORBIS: + ip3db_variant_set_word(&dst[IP3DBF_MUSIC_FILEFORMAT], 3); + break; + case PMPCODEC_WMA: + ip3db_variant_set_word(&dst[IP3DBF_MUSIC_FILEFORMAT], 5); + break; + } ip3db_variant_set_word(&dst[IP3DBF_MUSIC_TRACKNUMBER], (uint16_t)src->track_number); ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_BITRATE], src->bitrate); ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_UID], (uint32_t)i+1); + } ip3db_set(&pmpdbi->ip3db, array, num_records); free(array); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-28 14:52:17
|
Revision: 217 http://svn.sourceforge.net/pmplib/?rev=217&view=rev Author: nyaochi Date: 2006-12-28 06:52:13 -0800 (Thu, 28 Dec 2006) Log Message: ----------- An extended game: db.idx and db.dat do not have a fixed size. These files are found to be (n*0x00020000) bytes long if the database has a large number of entries. This commit fixes database dump. The fix for database writer follows later. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/dat.h trunk/pmplib/lib/pmp_iriverplus3/dic.c trunk/pmplib/lib/pmp_iriverplus3/dic.h trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 05:46:51 UTC (rev 216) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 14:52:13 UTC (rev 217) @@ -46,6 +46,15 @@ #include "dic.h" #include "dat.h" +#define PAGESIZE 0x00020000 + +typedef struct { + uint32_t size; + uint32_t num_entries; + uint32_t unknown1; + uint32_t next_page; +} page_header_t; + static void dat_entry_init(dat_entry_t* entry, const dic_table_t* dic_list) { memset(entry, 0, sizeof(*entry)); @@ -71,6 +80,30 @@ } } +static size_t dat_entry_size(dat_entry_t* entry) +{ + int i; + size_t size = 0; + for (i = 0;i < entry->num_fields;++i) { + ip3db_variant_t* var = &entry->fields[i]; + switch (var->type) { + case IP3DBVT_STRING: + size += var->value.str ? sizeof(ucs2char_t) * (ucs2len(var->value.str) + 1) : sizeof(ucs2char_t); + break; + case IP3DBVT_BYTE: + size += sizeof(uint8_t); + break; + case IP3DBVT_WORD: + size += sizeof(uint16_t); + break; + case IP3DBVT_DWORD: + size += sizeof(uint32_t); + break; + } + } + return size; +} + static size_t dat_entry_serialize(dat_entry_t* entry, uint8_t* block, uint8_t* q, uint32_t start, int is_storing) { int i; @@ -177,62 +210,78 @@ return &list->entries[list->num_entries++]; } -static size_t dat_list_serialize(dat_list_t* list, const dic_table_t* dic_list, uint8_t* buffer, uint32_t start, int is_storing) +static size_t dat_list_read(dat_list_t* list, page_header_t* header, const dic_table_t* dic_list, uint8_t* buffer, uint32_t start) { uint32_t i; uint8_t *p = buffer + start; - uint8_t *q = buffer + start + 0x00020000 - sizeof(uint32_t); + uint8_t *q = buffer + start + PAGESIZE - sizeof(uint32_t); - if (!is_storing) { - /* Read the header. */ - p += serialize_uint32be(p, &list->size, is_storing); - p += serialize_uint32be(p, &list->num_entries, is_storing); - p += serialize_uint32be(p, &list->unknown1, is_storing); - p += serialize_uint32be(p, &list->unknown2, is_storing); - } else { - /* Skip the header for now when writing. */ - p += sizeof(uint32_t) * 4; + /* Read the header. */ + p += serialize_uint32be(p, &header->size, 0); + p += serialize_uint32be(p, &header->num_entries, 0); + p += serialize_uint32be(p, &header->unknown1, 0); + p += serialize_uint32be(p, &header->next_page, 0); + + /* Expand the array of records. */ + list->entries = (dat_entry_t*)realloc(list->entries, sizeof(dat_entry_t) * (list->num_entries + header->num_entries)); + for (i = 0;i < header->num_entries;++i) { + dat_entry_init(&list->entries[list->num_entries+i], dic_list); } - /* Initialize fields according to db.dic when reading. */ - if (!is_storing) { - free(list->entries); - list->entries = (dat_entry_t*)calloc(list->num_entries, sizeof(dat_entry_t)); - for (i = 0;i < list->num_entries;++i) { - dat_entry_init(&list->entries[i], dic_list); - } + /* Read the new records. */ + for (i = 0;i < header->num_entries;++i) { + dat_entry_t* entry = &list->entries[list->num_entries+i]; + entry->offset = (uint32_t)(p - buffer); /* compute the current offset address */ + p += dat_entry_serialize(entry, p, q, start, 0); + q -= sizeof(uint32_t); } - /* Serialize entries in this table. */ - for (i = 0;i < list->num_entries;++i) { + list->num_entries += header->num_entries; + return (size_t)(header->size); +} + +static size_t dat_list_write(dat_list_t* list, uint32_t i, page_header_t* header, uint8_t* buffer, uint32_t start) +{ + uint8_t *p = buffer + start; + uint8_t *q = buffer + start + PAGESIZE - sizeof(uint32_t); + + header->size = 0; + header->num_entries = 0; + + /* Skip the header for now when writing. */ + p += sizeof(uint32_t) * 4; + + /* Write records. */ + while (i < list->num_entries) { + size_t free_space = (size_t)(q-p); dat_entry_t* entry = &list->entries[i]; + if (free_space < dat_entry_size(entry)) { + break; + } entry->offset = (uint32_t)(p - buffer); /* compute the current offset address */ - p += dat_entry_serialize(entry, p, q, start, is_storing); + p += dat_entry_serialize(entry, p, q, start, 1); q -= sizeof(uint32_t); + header->num_entries++; + i++; } - if (is_storing) { - /* Compute the block size and write the header. */ - list->size = (uint32_t)(p - (buffer + start)); - p = buffer + start; - p += serialize_uint32be(p, &list->size, is_storing); - p += serialize_uint32be(p, &list->num_entries, is_storing); - p += serialize_uint32be(p, &list->unknown1, is_storing); - p += serialize_uint32be(p, &list->unknown2, is_storing); + /* Compute the block size and write the header. */ + header->size = (uint32_t)(p - (buffer + start)); + if (list->num_entries <= i) { + header->next_page = 0; } - return (size_t)(list->size); + p = buffer + start; + p += serialize_uint32be(p, &header->size, 1); + p += serialize_uint32be(p, &header->num_entries, 1); + p += serialize_uint32be(p, &header->unknown1, 1); + p += serialize_uint32be(p, &header->next_page, 1); + return header->size; } static void dat_list_dump(dat_list_t* list, const dic_table_t* dic_list, FILE *fp) { uint32_t i; - - fprintf(fp, " size: 0x%08X\n", list->size); - fprintf(fp, " num_entries: %d\n", list->num_entries); - fprintf(fp, " unknown1: 0x%08X\n", list->unknown1); - fprintf(fp, " unknown2: 0x%08X\n", list->unknown2); - for (i = 0;i < list->num_entries;++i) { dat_entry_t* entry = &list->entries[i]; fprintf(fp, " ENTRY %d (0x%08X) = {\n", i, entry->offset); @@ -281,37 +330,73 @@ int dat_read(dat_t* dat, const dic_t* dic, FILE *fpi) { + page_header_t ph; long buffer_size = 0; uint8_t* buffer = NULL; + /* Read the whole image. */ fread_all(fpi, &buffer, &buffer_size); if (!buffer) { return 1; } - if (dat_serialize(dat, dic, buffer, 0) != 0) { - free(buffer); - return 1; + /* Clear Object records. */ + dat_list_finish(&dat->objects); + + /* Read Objects page(s) */ + dat_list_read(&dat->objects, &ph, &dic->objects, buffer, PAGESIZE * 0); + while (ph.next_page) { + dat_list_read(&dat->objects, &ph, &dic->objects, buffer, PAGESIZE * (ph.next_page - 1)); } + /* Clear Music records. */ + dat_list_finish(&dat->musics); + + /* Read Music page(s) */ + dat_list_read(&dat->musics, &ph, &dic->music, buffer, PAGESIZE * 1); + while (ph.next_page) { + dat_list_read(&dat->musics, &ph, &dic->music, buffer, PAGESIZE * (ph.next_page - 1)); + } + free(buffer); return 0; } int dat_write(dat_t* dat, const dic_t* dic, FILE *fpo) { - long buffer_size = 0x00040000; + uint32_t i = 0; + page_header_t ph; + long buffer_size = PAGESIZE * 2; uint8_t* buffer = (uint8_t*)calloc(buffer_size, sizeof(uint8_t)); if (!buffer) { return 1; } - if (dat_serialize(dat, dic, buffer, 1) != 0) { - free(buffer); - return 1; + /* Write Objects page(s) */ + i = 0; + memset(&ph, 0, sizeof(ph)); + ph.next_page = 3; + dat_list_write(&dat->objects, i, &ph, buffer, PAGESIZE * 0); + while (ph.next_page) { + uint32_t page = ph.next_page++; + buffer_size = PAGESIZE * page; + buffer = (uint8_t*)realloc(buffer, sizeof(uint8_t) * buffer_size); + i += ph.num_entries; + dat_list_write(&dat->objects, i, &ph, buffer, PAGESIZE * (page - 1)); } + /* Read Music page(s) */ + i = 0; + dat_list_write(&dat->musics, i, &ph, buffer, PAGESIZE * 1); + while (ph.next_page) { + uint32_t page = ph.next_page++; + buffer_size = PAGESIZE * page; + buffer = (uint8_t*)realloc(buffer, sizeof(uint8_t) * buffer_size); + i += ph.num_entries; + dat_list_write(&dat->objects, i, &ph, buffer, PAGESIZE * (page - 1)); + } + if (fwrite(buffer, 1, buffer_size, fpo) != buffer_size) { free(buffer); return 1; Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-28 05:46:51 UTC (rev 216) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-28 14:52:13 UTC (rev 217) @@ -31,10 +31,7 @@ } dat_entry_t; typedef struct { - uint32_t size; uint32_t num_entries; - uint32_t unknown1; - uint32_t unknown2; dat_entry_t* entries; } dat_list_t; Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-28 05:46:51 UTC (rev 216) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.c 2006-12-28 14:52:13 UTC (rev 217) @@ -194,7 +194,13 @@ { int i; uint32_t next = 0; - + uint8_t* p = buffer; + + p += serialize_uint32be(p, &dic->header.size, is_storing); + p += serialize_uint32be(p, &dic->header.num_dat_pages, is_storing); + p += serialize_uint32be(p, &dic->header.num_idx_pages, is_storing); + p += serialize_uint32be(p, &dic->header.unknown1, is_storing); + next = 0x0000003C; for (i = 0;i < dic->music.num_fields;++i) { dic_field_serialize(buffer + next, &dic->music.fields[i], is_storing); Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-28 05:46:51 UTC (rev 216) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-28 14:52:13 UTC (rev 217) @@ -25,6 +25,13 @@ #define __IP3DB_DIC_H__ typedef struct { + uint32_t size; + uint32_t num_dat_pages; + uint32_t num_idx_pages; + uint32_t unknown1; +} dic_header_t; + +typedef struct { uint32_t next; uint32_t type; uint32_t idx_root; @@ -45,8 +52,9 @@ } dic_table_t; struct tag_dic_t { - dic_table_t music; - dic_table_t objects; + dic_header_t header; + dic_table_t music; + dic_table_t objects; uint8_t* buffer; long size; Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 05:46:51 UTC (rev 216) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 14:52:13 UTC (rev 217) @@ -619,9 +619,8 @@ idx_header_t* header = (idx_header_t*)idx->buffer; /* Read the whole data at a time. */ - if (fread(idx->buffer, 1, idx->max_size, fpi) != idx->max_size) { - return 1; - } + fread_all(fpi, &idx->buffer, &idx->max_size); + idx->avl->buffer = idx->buffer; /* Convert the byte order of the header from big endian to the native one. */ from_uint32be(&header->size); Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-28 05:46:51 UTC (rev 216) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-28 14:52:13 UTC (rev 217) @@ -78,7 +78,7 @@ { var->type = IP3DBVT_STRING; ucs2free(var->value.str); - var->value.str = ucs2dup(val); + var->value.str = val ? ucs2dup(val) : ucs2calloc(sizeof(ucs2char_t)); } void ip3db_variant_clone(ip3db_variant_t* dst, const ip3db_variant_t* src) Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-28 05:46:51 UTC (rev 216) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-28 14:52:13 UTC (rev 217) @@ -116,8 +116,10 @@ * Fields chunks in db.dat. */ enum { + IP3DBIDX_NONE = -1, IP3DBIDX_MUSIC = 0, IP3DBIDX_OBJECTS, + IP3DBIDX_LAST, }; /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-28 16:22:45
|
Revision: 218 http://svn.sourceforge.net/pmplib/?rev=218&view=rev Author: nyaochi Date: 2006-12-28 08:22:43 -0800 (Thu, 28 Dec 2006) Log Message: ----------- Continued effort to support large database. Implemented writing routine. This revision still has some bugs. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/dat.h trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/idx.h trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 14:52:13 UTC (rev 217) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 16:22:43 UTC (rev 218) @@ -309,25 +309,6 @@ free(dat); } -static size_t dat_serialize(dat_t* dat, const dic_t* dic, uint8_t* buffer, int is_storing) -{ - if (is_storing) { - /* For writing a music chunk only. - * Empty filepath and filename fields as iriver plus 3 does. - */ - int i; - for (i = 0;i < dat->musics.num_entries;++i) { - static const ucs2char_t empty[] = {0}; - dat_entry_t* entry = &dat->musics.entries[i]; - ip3db_variant_set_str(&entry->fields[IP3DBF_MUSIC_FILEPATH], empty); - ip3db_variant_set_str(&entry->fields[IP3DBF_MUSIC_FILENAME], empty); - } - } - dat_list_serialize(&dat->objects, &dic->objects, buffer, 0, is_storing); - dat_list_serialize(&dat->musics, &dic->music, buffer, 0x00020000, is_storing); - return 0; -} - int dat_read(dat_t* dat, const dic_t* dic, FILE *fpi) { page_header_t ph; @@ -362,7 +343,7 @@ return 0; } -int dat_write(dat_t* dat, const dic_t* dic, FILE *fpo) +int dat_write(dat_t* dat, dic_t* dic, FILE *fpo) { uint32_t i = 0; page_header_t ph; @@ -378,23 +359,27 @@ memset(&ph, 0, sizeof(ph)); ph.next_page = 3; dat_list_write(&dat->objects, i, &ph, buffer, PAGESIZE * 0); + dic->header.num_dat_pages = 1; while (ph.next_page) { uint32_t page = ph.next_page++; buffer_size = PAGESIZE * page; buffer = (uint8_t*)realloc(buffer, sizeof(uint8_t) * buffer_size); i += ph.num_entries; dat_list_write(&dat->objects, i, &ph, buffer, PAGESIZE * (page - 1)); + dic->header.num_dat_pages += 1; } /* Read Music page(s) */ i = 0; dat_list_write(&dat->musics, i, &ph, buffer, PAGESIZE * 1); + dic->header.num_dat_pages += 1; while (ph.next_page) { uint32_t page = ph.next_page++; buffer_size = PAGESIZE * page; buffer = (uint8_t*)realloc(buffer, sizeof(uint8_t) * buffer_size); i += ph.num_entries; dat_list_write(&dat->objects, i, &ph, buffer, PAGESIZE * (page - 1)); + dic->header.num_dat_pages += 1; } if (fwrite(buffer, 1, buffer_size, fpo) != buffer_size) { Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-28 14:52:13 UTC (rev 217) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-28 16:22:43 UTC (rev 218) @@ -44,7 +44,7 @@ dat_t* dat_new(); void dat_finish(dat_t* dat); int dat_read(dat_t* dat, const dic_t* dic, FILE *fpi); -int dat_write(dat_t* dat, const dic_t* dic, FILE *fpo); +int dat_write(dat_t* dat, dic_t* dic, FILE *fpo); void dat_dump(dat_t* dat, const dic_t* dic, FILE *fp); void dat_set(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records); Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 14:52:13 UTC (rev 217) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 16:22:43 UTC (rev 218) @@ -55,8 +55,17 @@ #include "dat.h" #include "idx.h" +#define PAGESIZE 0x00020000 + #define COMP(a, b) ((a)>(b))-((a)<(b)) +struct tag_header_t { + uint32_t size; + uint32_t unknown1; + uint32_t unknown2; +}; +typedef struct tag_header_t header_t; + struct tag_avlnode_t { uint32_t left; uint32_t right; @@ -80,6 +89,17 @@ typedef int (*avl_comp_t)(avl_t* avl, uint32_t x, uint32_t y); +static avl_t* avl_new() +{ + return (avl_t*)calloc(1, sizeof(avl_t)); +} + +static void avl_finish(avl_t* avl) +{ + free(avl->buffer); + free(avl); +} + static uint32_t avl_current(avl_t* avl) { return avl->offset; @@ -87,8 +107,27 @@ static uint32_t avl_allocate(avl_t* avl, uint32_t size) { - uint32_t offset = avl->offset; + header_t* header = NULL; + uint32_t base = 0, offset = 0; + + /* Expand the memory block if necessary. */ + if (avl->size < avl->offset + size) { + uint32_t newsize = avl->size + PAGESIZE; + avl->buffer = (uint8_t*)realloc(avl->buffer, sizeof(uint8_t) * newsize); + memset(avl->buffer + avl->size, 0, PAGESIZE); + avl->offset = avl->size + sizeof(header_t); + avl->size = newsize; + } + + /* Allocate a memory block. */ + offset = avl->offset; avl->offset += size; + + /* Store the size of the current page. */ + base = avl->size - PAGESIZE; + header = (header_t*)(avl->buffer + base); + header->size = avl->offset - base; + return offset; } @@ -595,37 +634,33 @@ idx_t *idx_new() { - idx_t* idx = (idx_t*)malloc(sizeof(idx_t)); - idx->max_size = 0x00020000; - idx->buffer = (uint8_t*)malloc(idx->max_size); - idx->size = 0; - idx->avl = (avl_t*)malloc(sizeof(avl_t)); - idx->avl->buffer = idx->buffer; - idx->avl->offset = sizeof(idx_header_t); - idx->avl->size = idx->max_size; + idx_t* idx = (idx_t*)calloc(1, sizeof(idx_t)); + idx->avl = avl_new(); return idx; } void idx_finish(idx_t* idx) { - free(idx->avl); - free(idx->buffer); + avl_finish(idx->avl); free(idx); } int idx_read(idx_t* idx, dic_t* dic, FILE *fpi) { int i; - idx_header_t* header = (idx_header_t*)idx->buffer; + uint32_t offset = 0; /* Read the whole data at a time. */ - fread_all(fpi, &idx->buffer, &idx->max_size); - idx->avl->buffer = idx->buffer; + fread_all(fpi, &idx->avl->buffer, &idx->avl->size); /* Convert the byte order of the header from big endian to the native one. */ - from_uint32be(&header->size); - from_uint32be(&header->unknown1); - from_uint32be(&header->unknown2); + while (offset < idx->avl->size) { + idx_header_t* header = (idx_header_t*)(idx->avl->buffer + offset); + from_uint32be(&header->size); + from_uint32be(&header->unknown1); + from_uint32be(&header->unknown2); + offset += PAGESIZE; + } /* Convert the byte order of values in AVL trees. */ for (i = 0;i < dic->music.num_indices;++i) { @@ -642,15 +677,16 @@ result_t idx_write(idx_t* idx, dic_t* dic, FILE *fpo) { int i; - idx_header_t* header = (idx_header_t*)idx->buffer; + uint32_t offset = 0; - /* The size fo db.idx equals to the maximum offset of the AVL trees. */ - header->size = idx->avl->offset; - /* Convert the byte order of the header to big endian from the native one. */ - to_uint32be(&header->size); - to_uint32be(&header->unknown1); - to_uint32be(&header->unknown2); + while (offset < idx->avl->size) { + idx_header_t* header = (idx_header_t*)(idx->avl->buffer + offset); + to_uint32be(&header->size); + to_uint32be(&header->unknown1); + to_uint32be(&header->unknown2); + offset += PAGESIZE; + } /* Convert the byte order of values in AVL trees. */ for (i = 0;i < dic->music.num_indices;++i) { @@ -663,25 +699,20 @@ } /* Read the whole data at a time. */ - if (fwrite(idx->buffer, 1, idx->max_size, fpo) != idx->max_size) { + if (fwrite(idx->avl->buffer, 1, idx->avl->size, fpo) != idx->avl->size) { return 1; } + dic->header.num_idx_pages = (idx->avl->size / PAGESIZE); return 0; } result_t idx_dump(idx_t* idx, dic_t* dic, FILE *fpo) { int i; - idx_header_t* header = (idx_header_t*)idx->buffer; fprintf(fpo, "===== db.idx =====\n"); - /* Dump the header. */ - fprintf(fpo, "size: 0x%08X\n", header->size); - fprintf(fpo, "unknown1: 0x%08X\n", header->unknown1); - fprintf(fpo, "unknown2: 0x%08X\n", header->unknown2); - /* Dump the binary search trees. */ for (i = 0;i < dic->music.num_indices;++i) { uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_MUSIC, i); @@ -735,10 +766,8 @@ { int index; - memset(idx->buffer, 0, idx->max_size); - idx->avl->buffer = idx->buffer; - idx->avl->offset = sizeof(idx_header_t); - idx->avl->size = idx->max_size; + avl_finish(idx->avl); + idx->avl = avl_new(); for (index = 0;index < dic->music.num_indices;++index) { uint32_t root = 0; Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.h 2006-12-28 14:52:13 UTC (rev 217) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.h 2006-12-28 16:22:43 UTC (rev 218) @@ -27,9 +27,6 @@ struct tag_avl_t; typedef struct tag_avl_t avl_t; struct tag_idx_t { - uint8_t* buffer; - uint32_t size; - uint32_t max_size; avl_t* avl; }; typedef struct tag_idx_t idx_t; Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-28 14:52:13 UTC (rev 217) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-28 16:22:43 UTC (rev 218) @@ -65,7 +65,7 @@ "iriver_e10_ums_1.04", "E10 UMS", "UM", "1.04", "1.04", "System\\E10.SYS", "System\\db.dat", "System\\db.dic", "System\\db.idx", - "", "Playlists\\", + "Music2\\", "Playlists\\", ".plp", }, { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-28 16:56:02
|
Revision: 219 http://svn.sourceforge.net/pmplib/?rev=219&view=rev Author: nyaochi Date: 2006-12-28 08:56:01 -0800 (Thu, 28 Dec 2006) Log Message: ----------- Do not cross a page boundary with AVL node and key. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/idx.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 16:22:43 UTC (rev 218) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-28 16:56:01 UTC (rev 219) @@ -369,7 +369,15 @@ dic->header.num_dat_pages += 1; } - /* Read Music page(s) */ + /* Clear filepath and filename */ + for (i = 0;i < dat->musics.num_entries;++i) { + static const ucs2char_t empty[] = {0}; + dat_entry_t* entry = &dat->musics.entries[i]; + ip3db_variant_set_str(&entry->fields[IP3DBF_MUSIC_FILEPATH], empty); + ip3db_variant_set_str(&entry->fields[IP3DBF_MUSIC_FILENAME], empty); + } + + /* Write Music page(s) */ i = 0; dat_list_write(&dat->musics, i, &ph, buffer, PAGESIZE * 1); dic->header.num_dat_pages += 1; @@ -378,7 +386,7 @@ buffer_size = PAGESIZE * page; buffer = (uint8_t*)realloc(buffer, sizeof(uint8_t) * buffer_size); i += ph.num_entries; - dat_list_write(&dat->objects, i, &ph, buffer, PAGESIZE * (page - 1)); + dat_list_write(&dat->musics, i, &ph, buffer, PAGESIZE * (page - 1)); dic->header.num_dat_pages += 1; } Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 16:22:43 UTC (rev 218) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 16:56:01 UTC (rev 219) @@ -142,9 +142,9 @@ avl->offset = offset; } -static uint32_t avlnode_new(avl_t* avl) +static uint32_t avlnode_new(avl_t* avl, size_t keysize) { - uint32_t offset = avl_allocate(avl, sizeof(avlnode_t)); + uint32_t offset = avl_allocate(avl, sizeof(avlnode_t) + keysize); avlnode_t* a = avlnode(avl, offset); a->left = 0; a->right = 0; @@ -332,25 +332,28 @@ int ret = 0; static avl_comp_t comp[] = {NULL, avl_comp_ucs2string, avl_comp_byte, avl_comp_word, avl_comp_dword}; uint32_t offset_prev = avl_current(avl); - uint32_t offset_this = avlnode_new(avl); - size_t size = 0; + uint32_t offset_this = 0; uint32_t offset_key = 0; switch (type) { case IP3DBVT_BYTE: - offset_key = avl_allocate(avl, sizeof(uint8_t)); + offset_this = avlnode_new(avl, sizeof(uint8_t)); + offset_key = offset_this + sizeof(avlnode_t); *((uint8_t*)avlnode(avl, offset_key)) = key->value.byte; break; case IP3DBVT_WORD: - offset_key = avl_allocate(avl, sizeof(uint16_t)); + offset_this = avlnode_new(avl, sizeof(uint16_t)); + offset_key = offset_this + sizeof(avlnode_t); *((uint16_t*)avlnode(avl, offset_key)) = key->value.word; break; case IP3DBVT_DWORD: - offset_key = avl_allocate(avl, sizeof(uint32_t)); + offset_this = avlnode_new(avl, sizeof(uint32_t)); + offset_key = offset_this + sizeof(avlnode_t); *((uint32_t*)avlnode(avl, offset_key)) = key->value.dword; break; case IP3DBVT_STRING: - offset_key = avl_allocate(avl, sizeof(ucs2char_t) * (ucs2len(key->value.str) + 1)); + offset_this = avlnode_new(avl, sizeof(ucs2char_t) * (ucs2len(key->value.str) + 1)); + offset_key = offset_this + sizeof(avlnode_t); ucs2cpy((ucs2char_t*)avlnode(avl, offset_key), key->value.str); break; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-28 17:19:12
|
Revision: 220 http://svn.sourceforge.net/pmplib/?rev=220&view=rev Author: nyaochi Date: 2006-12-28 09:19:09 -0800 (Thu, 28 Dec 2006) Log Message: ----------- Fixed a bug. Pointers might be invalid after a realloc() call. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 16:56:01 UTC (rev 219) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-28 17:19:09 UTC (rev 220) @@ -743,11 +743,23 @@ int type = dictbl->fields[field].type; int ret = avl_insert_key(idx->avl, &entry->fields[field], type, &offset, root); if (level+1 < IP3DBIDX_MAX_KEYLEVEL && dictbl->indices[index].fields[level+1] != -1) { + /* The following code does not work since we cannot guarantee that node->tail + * is valid after idx_insert_dat() call, which may move the memory block to + * expand it (realloc). + * avlnode_t* node = avlnode(idx->avl, offset); + * idx_insert_dat(idx, dictbl, &node->tail, entry, index, level+1); + * Therefore, we need to update node->tail after idx_insert_dat() call. + */ avlnode_t* node = avlnode(idx->avl, offset); - idx_insert_dat(idx, dictbl, &node->tail, entry, index, level+1); + uint32_t child = node->tail; + idx_insert_dat(idx, dictbl, &child, entry, index, level+1); + node = avlnode(idx->avl, offset); + node->tail = child; } else { + /* The same here. We must obtain the pointer to the node after avltail_new() call. + */ + uint32_t offset_tail = avltail_new(idx->avl); avlnode_t* node = avlnode(idx->avl, offset); - uint32_t offset_tail = avltail_new(idx->avl); avltail_t* tail = (avltail_t*)avlnode(idx->avl, offset_tail); tail->data = entry->offset; tail->next = node->tail; Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-28 16:56:01 UTC (rev 219) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-28 17:19:09 UTC (rev 220) @@ -65,7 +65,7 @@ "iriver_e10_ums_1.04", "E10 UMS", "UM", "1.04", "1.04", "System\\E10.SYS", "System\\db.dat", "System\\db.dic", "System\\db.idx", - "Music2\\", "Playlists\\", + "", "Playlists\\", ".plp", }, { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-29 07:04:12
|
Revision: 228 http://svn.sourceforge.net/pmplib/?rev=228&view=rev Author: nyaochi Date: 2006-12-28 23:04:13 -0800 (Thu, 28 Dec 2006) Log Message: ----------- Small fix to build pmp_iriverplus3 with gcc Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.h trunk/pmplib/lib/pmp_iriverplus3/dic.h trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/idx.h Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-29 06:51:31 UTC (rev 227) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-29 07:04:13 UTC (rev 228) @@ -39,7 +39,6 @@ dat_list_t objects; dat_list_t musics; }; -typedef struct tag_dat_t dat_t; dat_t* dat_new(); void dat_finish(dat_t* dat); Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-29 06:51:31 UTC (rev 227) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.h 2006-12-29 07:04:13 UTC (rev 228) @@ -59,7 +59,6 @@ uint8_t* buffer; long size; }; -typedef struct tag_dic_t dic_t; dic_t* dic_new(); void dic_finish(dic_t* dic); Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-29 06:51:31 UTC (rev 227) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2006-12-29 07:04:13 UTC (rev 228) @@ -85,7 +85,6 @@ uint32_t size; uint32_t offset; }; -typedef struct tag_avl_t avl_t; typedef int (*avl_comp_t)(avl_t* avl, uint32_t x, uint32_t y); Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.h 2006-12-29 06:51:31 UTC (rev 227) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.h 2006-12-29 07:04:13 UTC (rev 228) @@ -29,7 +29,6 @@ struct tag_idx_t { avl_t* avl; }; -typedef struct tag_idx_t idx_t; idx_t *idx_new(); void idx_finish(idx_t* idx); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2006-12-31 07:38:08
|
Revision: 230 http://svn.sourceforge.net/pmplib/?rev=230&view=rev Author: nyaochi Date: 2006-12-30 23:38:06 -0800 (Sat, 30 Dec 2006) Log Message: ----------- - Database update for iriver E10. - Playlist conversion for iriver E10. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/dat.h trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.vcproj trunk/pmplib/lib/pmp_iriverplus3/util.c trunk/pmplib/lib/pmp_iriverplus3/util.h Added Paths: ----------- trunk/pmplib/lib/pmp_iriverplus3/playlist.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-29 15:59:14 UTC (rev 229) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2006-12-31 07:38:06 UTC (rev 230) @@ -47,6 +47,7 @@ #include "dat.h" #define PAGESIZE 0x00020000 +#define COMP(a, b) ((a)>(b))-((a)<(b)) typedef struct { uint32_t size; @@ -55,6 +56,11 @@ uint32_t next_page; } page_header_t; +struct tag_sort_index_t { + const void* base; + int index; +}; + static void dat_entry_init(dat_entry_t* entry, const dic_table_t* dic_list) { memset(entry, 0, sizeof(*entry)); @@ -292,9 +298,75 @@ +static int comp_object_uid(const void *__x, const void *__y) +{ + const sort_index_t* _x = (const sort_index_t*)__x; + const sort_index_t* _y = (const sort_index_t*)__y; + const dat_list_t* _xb = (const dat_list_t*)_x->base; + const dat_list_t* _yb = (const dat_list_t*)_y->base; + const ip3db_variant_t* x = _xb->entries[_x->index].fields; + const ip3db_variant_t* y = _yb->entries[_y->index].fields; + return COMP(x[IP3DBF_OBJECTS_UID].value.dword, y[IP3DBF_OBJECTS_UID].value.dword); +} + +static sort_index_t* dat_uidmap_create(dat_list_t* list) +{ + int i; + sort_index_t* si = (sort_index_t*)malloc(sizeof(sort_index_t) * list->num_entries); + + if (si) { + /* Sort UIDs. */ + for (i = 0;i < list->num_entries;++i) { + si[i].base = list; + si[i].index = i; + } + qsort(si, list->num_entries, sizeof(si[0]), comp_object_uid); + } + return si; +} + +static void dat_uidmap_finish(sort_index_t* si) +{ + free(si); +} + +static int dat_uidmap_get(sort_index_t* si, dat_list_t* list, uint32_t uid) +{ + int low = 0, high = list->num_entries-1; + + /* Binary search. */ + while (low <= high) { + int middle = (low + high) / 2; + int comp = COMP(uid, list->entries[si[middle].index].fields[IP3DBF_OBJECTS_UID].value.dword); + if (comp == 0) { + /* Found */ + return si[middle].index; + } else if (comp < 0) { + high = middle - 1; + } else { + low = middle + 1; + } + } + return -1; +} + +static ucs2char_t* ucs2append(const ucs2char_t* x, const ucs2char_t* y) +{ + ucs2char_t* ret = NULL; + size_t length = 0; + length += x ? ucs2len(x) : 0; + length += y ? ucs2len(y) : 0; + ret = ucs2calloc(sizeof(ucs2char_t) * (length+1)); + if (x) ucs2cat(ret, x); + if (y) ucs2cat(ret, y); + return ret; +} + + + dat_t* dat_new() { - dat_t* dat = (dat_t*)malloc(sizeof(dat_t)); + dat_t* dat = (dat_t*)calloc(1, sizeof(dat_t)); if (dat) { dat_list_init(&dat->objects); dat_list_init(&dat->musics); @@ -311,6 +383,7 @@ int dat_read(dat_t* dat, const dic_t* dic, FILE *fpi) { + uint32_t i = 0; page_header_t ph; long buffer_size = 0; uint8_t* buffer = NULL; @@ -330,6 +403,10 @@ dat_list_read(&dat->objects, &ph, &dic->objects, buffer, PAGESIZE * (ph.next_page - 1)); } + /* Construct Object UID -> dat->objects[i] mapping table. */ + dat_uidmap_finish(dat->objects_uidmap); + dat->objects_uidmap = dat_uidmap_create(&dat->objects); + /* Clear Music records. */ dat_list_finish(&dat->musics); @@ -339,6 +416,48 @@ dat_list_read(&dat->musics, &ph, &dic->music, buffer, PAGESIZE * (ph.next_page - 1)); } + /* Set filename and pathname fields. */ + for (i = 0;i < dat->musics.num_entries;++i) { + dat_entry_t* entry = &dat->musics.entries[i]; + int index = dat_uidmap_get(dat->objects_uidmap, &dat->objects, entry->fields[IP3DBF_MUSIC_UID].value.dword); + if (0 <= index) { + static const ucs2char_t ucs2cs_root[] = {'/',0}; + ucs2char_t* pathname = NULL; + ucs2char_t* tmp = NULL; + size_t length = 0; + + /* Set the filename. */ + ip3db_variant_set_str( + &entry->fields[IP3DBF_MUSIC_FILENAME], + dat->objects.entries[index].fields[IP3DBF_OBJECTS_OBJECTNAME].value.str + ); + + /* Obtain the pathname by tracing parent UIDs. */ + for (;;) { + uint32_t parent_uid = dat->objects.entries[index].fields[IP3DBF_OBJECTS_PARENTUID].value.dword; + if (parent_uid == 0xFFFFFFFF) { + break; + } + index = dat_uidmap_get(dat->objects_uidmap, &dat->objects, parent_uid); + if (index < 0) { + break; + } + tmp = ucs2append( + dat->objects.entries[index].fields[IP3DBF_OBJECTS_OBJECTNAME].value.str, + pathname + ); + ucs2free(pathname); + pathname = tmp; + } + + tmp = ucs2append(ucs2cs_root, pathname); + ucs2free(pathname); + pathname = tmp; + ip3db_variant_set_str(&entry->fields[IP3DBF_MUSIC_FILEPATH], pathname); + ucs2free(pathname); + } + } + free(buffer); return 0; } @@ -484,17 +603,14 @@ -typedef struct { - const ip3db_music_record_t* base; - int index; -} sort_index_t; - static int comp_pathname(const void *__x, const void *__y) { const sort_index_t* _x = (const sort_index_t*)__x; const sort_index_t* _y = (const sort_index_t*)__y; - const ip3db_variant_t* x = _x->base[_x->index]; - const ip3db_variant_t* y = _y->base[_y->index]; + const ip3db_music_record_t* _xb = (const ip3db_music_record_t*)_x->base; + const ip3db_music_record_t* _yb = (const ip3db_music_record_t*)_y->base; + const ip3db_variant_t* x = _xb[_x->index]; + const ip3db_variant_t* y = _yb[_y->index]; int ret = ucs2cmp(x[IP3DBF_MUSIC_FILEPATH].value.str, y[IP3DBF_MUSIC_FILEPATH].value.str); if (ret == 0) { return ucs2cmp(x[IP3DBF_MUSIC_FILENAME].value.str, y[IP3DBF_MUSIC_FILENAME].value.str); @@ -554,6 +670,7 @@ /* Clear all entries. */ dat_list_finish(dato); dat_list_finish(datm); + dat_uidmap_finish(dat->objects_uidmap); /* Append an entry for the root directory. */ entry = dat_list_expand(dato); @@ -638,4 +755,6 @@ } dircache_finish(&dc); + + dat->objects_uidmap = dat_uidmap_create(&dat->objects); } Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-29 15:59:14 UTC (rev 229) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.h 2006-12-31 07:38:06 UTC (rev 230) @@ -35,9 +35,12 @@ dat_entry_t* entries; } dat_list_t; +struct tag_sort_index_t; typedef struct tag_sort_index_t sort_index_t; + struct tag_dat_t { dat_list_t objects; dat_list_t musics; + sort_index_t* objects_uidmap; }; dat_t* dat_new(); Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-29 15:59:14 UTC (rev 229) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2006-12-31 07:38:06 UTC (rev 230) @@ -220,6 +220,16 @@ return 0; } +int ip3db_num_records(ip3db_t* db) +{ + return (int)db->dat->musics.num_entries; +} + +ip3db_music_record_t* ip3db_get_record(ip3db_t* db, int i) +{ + return (ip3db_music_record_t*)db->dat->musics.entries[i].fields; +} + void ip3db_record_init(ip3db_t* db, ip3db_music_record_t* record) { int i; Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-29 15:59:14 UTC (rev 229) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2006-12-31 07:38:06 UTC (rev 230) @@ -181,7 +181,16 @@ result_t ip3db_read(ip3db_t* db, const ucs2char_t* datfn, const ucs2char_t* dicfn, const ucs2char_t* idxfn); result_t ip3db_write(ip3db_t* db, const ucs2char_t* datfn, const ucs2char_t* dicfn, const ucs2char_t* idxfn); result_t ip3db_set(ip3db_t* db, const ip3db_music_record_t* records, int num_records); +int ip3db_num_records(ip3db_t* db); +ip3db_music_record_t* ip3db_get_record(ip3db_t* db, int i); result_t ip3db_dump(ip3db_t* db, FILE *fpo); +int ip3db_playlist_write( + ip3db_t* db, + const ucs2char_t *filename, + ucs2char_t* const mediafiles[], + int num_mediafiles, + const ucs2char_t *path_to_root + ); void ip3db_record_init(ip3db_t* db, ip3db_music_record_t* record); Added: trunk/pmplib/lib/pmp_iriverplus3/playlist.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/playlist.c (rev 0) +++ trunk/pmplib/lib/pmp_iriverplus3/playlist.c 2006-12-31 07:38:06 UTC (rev 230) @@ -0,0 +1,120 @@ +/* + * Playlist reader/writer for iriver E10. + * + * Copyright (c) 2005-2006 Nyaochi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif/*HAVE_CONFIG_H*/ + +#include <os.h> +#include <stdio.h> +#include <stdlib.h> +#include <ucs2char.h> +#include <filepath.h> + +#include "serialize.h" +#include "util.h" +#include "ip3db.h" +#include "dat.h" + +static uint32_t findfile(ip3db_t* db, const ucs2char_t *filename, const ucs2char_t *path_to_root) +{ + int i; + const ucs2char_t *filepart = filepath_skippath(filename); + const ucs2char_t *pathfile = filepath_skipdrive(filename, path_to_root); + ucs2char_t *pathname = alloca(sizeof(ucs2char_t) * (ucs2len(pathfile) + 1)); + + ucs2cpy(pathname, pathfile); + filepath_remove_filespec(pathname); + filepath_addslash(pathname); + filepath_slash(pathname); + + for (i = 0;i < db->dat->musics.num_entries;++i) { + dat_entry_t* entry = &db->dat->musics.entries[i]; + if (ucs2icmp(entry->fields[IP3DBF_MUSIC_FILENAME].value.str, filepart) == 0 && + ucs2icmp(entry->fields[IP3DBF_MUSIC_FILEPATH].value.str, pathname) == 0) { + return entry->fields[IP3DBF_MUSIC_UID].value.dword; + } + } + return 0; +} + +int ip3db_playlist_write( + ip3db_t* db, + const ucs2char_t *filename, + ucs2char_t* const mediafiles[], + int num_mediafiles, + const ucs2char_t *path_to_root + ) +{ + int i; + FILE *fp = NULL; + uint32_t* uids = NULL; + uint32_t num_uids = 0; + + for (i = 0;i < num_mediafiles;i++) { + if (mediafiles[i][0]) { + uint32_t uid = 0; + ucs2char_t mediafile[MAX_PATH]; + ucs2cpy(mediafile, mediafiles[i]); + + uid = findfile(db, mediafile, path_to_root); + if (uid <= 0) { + goto error_exit; + } + + uids = realloc(uids, sizeof(uint32_t) * (num_uids+1)); + if (!uids) { + goto error_exit; + } + uids[num_uids++] = uid; + } + } + + fp = ucs2fopen(filename, "wb"); + if (fp) { + size_t size = sizeof(uint32_t) + sizeof(uint32_t) * num_uids; + uint8_t* buffer = (uint8_t*)malloc(size); + uint8_t* p = buffer; + + if (!buffer) { + goto error_exit; + } + + p += serialize_uint32le(p, &num_uids, 1); + for (i = 0;i < (int)num_uids;++i) { + p += serialize_uint32le(p, &uids[i], 1); + } + fwrite(buffer, 1, size, fp); + free(buffer); + fclose(fp); + } else { + return -1; + } + + free(uids); + return 0; + +error_exit: + free(uids); + return -1; +} Property changes on: trunk/pmplib/lib/pmp_iriverplus3/playlist.c ___________________________________________________________________ Name: svn:keywords + Id Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-29 15:59:14 UTC (rev 229) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2006-12-31 07:38:06 UTC (rev 230) @@ -37,6 +37,7 @@ #include <pmphelp.h> #include "ip3db.h" +#include "util.h" #ifdef PMP_IRIVERPLUS3_EXPORTS #define PMPIRIVERPLUS3API __declspec(dllexport) @@ -62,8 +63,8 @@ static const ip3model_descriptor_t g_model_descriptions[] = { { - "iriver_e10_ums_1.04", "E10 UMS", "UM", - "1.04", "1.04", + "iriver_e10_ums_1.00-1.04", "E10 UMS", "UM", + "1.00", "1.04", "System\\E10.SYS", "System\\db.dat", "System\\db.dic", "System\\db.idx", "", "Playlists\\", ".plp", @@ -433,7 +434,30 @@ pmppl_internal_t* pmppli = NULL; *ptr_pmppl = 0; - return PMP_NOTIMPLIMENTED; + + pmppl = calloc(1, sizeof(pmppl_t)); + if (!pmppl) { + 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); + return PMPDBE_OUTOFMEMORY; + } + ip3db_init(&pmppli->ip3db); + ip3db_read(&pmppli->ip3db, pmpi->env.dat_filename, pmpi->env.dic_filename, pmpi->env.idx_filename); + + pmppl->pmp = pmp; + pmppl->instance = pmppli; + + pmppl->add_ref(pmppl); + *ptr_pmppl = pmppl; + return 0; } @@ -515,38 +539,22 @@ return (path + length); } -static int _filepath_slash(ucs2char_t* path) -{ - while (*path) { - if (*path == 0x005C) { - *path = 0x002F; - } - path++; - } - return 0; -} - static result_t pmpdb_set(pmpdb_t* pmpdb, const pmp_record_t* records, uint32_t num_records) { int i; pmpdb_internal_t* pmpdbi = (pmpdb_internal_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_music_record_t* array = (ip3db_music_record_t*)malloc(sizeof(ip3db_music_record_t) * num_records); - ucs2cpy(path_to_root, pmpi->env.path_to_root); - _filepath_removeslash(path_to_root); - for (i = 0;i < num_records;++i) { const pmp_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], src->filename + ucs2len(path_to_root)); + ip3db_variant_set_str(&dst[IP3DBF_MUSIC_FILEPATH], filepath_skipdrive(src->filename, pmpi->env.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); + filepath_slash(dst[IP3DBF_MUSIC_FILEPATH].value.str); ip3db_variant_set_str(&dst[IP3DBF_MUSIC_FILENAME], filepath_skippath(src->filename)); ip3db_variant_set_str(&dst[IP3DBF_MUSIC_ARTIST], src->artist); ip3db_variant_set_str(&dst[IP3DBF_MUSIC_ALBUM], src->album); @@ -567,21 +575,67 @@ } ip3db_variant_set_word(&dst[IP3DBF_MUSIC_TRACKNUMBER], (uint16_t)src->track_number); ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_BITRATE], src->bitrate); + ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_CLUSA], src->ts_update); ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_UID], (uint32_t)i+1); } ip3db_set(&pmpdbi->ip3db, array, num_records); free(array); return 0; - //return ip2db_set(&pmpdbi->ip2db, records, num_records, pmpi->env.path_to_root); -} + } static result_t pmpdb_get(pmpdb_t* pmpdb, pmp_record_t* records, uint32_t* num_records) { pmpdb_internal_t* pmpdbi = (pmpdb_internal_t*)pmpdb->instance; pmp_internal_t* pmpi = (pmp_internal_t*)pmpdb->pmp->instance; - return PMP_NOTIMPLIMENTED; - //return ip2db_get(&pmpdbi->ip2db, records, num_records, pmpi->env.path_to_root); + 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); + + if (!records) { + *num_records = (uint32_t)n; + return 0; + } + + for (i = 0;i < n;++i) { + const ip3db_variant_t* src = (const ip3db_variant_t*)ip3db_get_record(db, i); + pmp_record_t* dst = &records[i]; + size_t length = 0; + + pmp_record_init(dst); + + length = ucs2len(pmpi->env.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); + ucs2cat(dst->filename, src[IP3DBF_MUSIC_FILEPATH].value.str+1); + ucs2cat(dst->filename, src[IP3DBF_MUSIC_FILENAME].value.str); + filepath_backslash(dst->filename); + + dst->title = ucs2dup(src[IP3DBF_MUSIC_TITLE].value.str); + dst->artist = ucs2dup(src[IP3DBF_MUSIC_ARTIST].value.str); + dst->album = ucs2dup(src[IP3DBF_MUSIC_ALBUM].value.str); + dst->genre = ucs2dup(src[IP3DBF_MUSIC_GENRE].value.str); + dst->date = ucs2dup(src[IP3DBF_MUSIC_ORGRELEASEDATE].value.str); + switch (src[IP3DBF_MUSIC_FILEFORMAT].value.word) { + case 0: + dst->codec = PMPCODEC_MPEGLAYER3; + break; + case 3: + dst->codec = PMPCODEC_VORBIS; + break; + case 5: + dst->codec = PMPCODEC_WMA; + break; + } + dst->track_number = src[IP3DBF_MUSIC_TRACKNUMBER].value.word; + dst->bitrate = src[IP3DBF_MUSIC_BITRATE].value.dword; + dst->duration = src[IP3DBF_MUSIC_DURATION].value.dword; + dst->ts_update = src[IP3DBF_MUSIC_CLUSA].value.dword; + dst->rating = src[IP3DBF_MUSIC_RATING].value.word; + } + return 0; } static result_t pmpdb_dump(pmpdb_t* pmpdb, FILE *fp, int level) @@ -618,11 +672,8 @@ { pmppl_internal_t* pmppli = (pmppl_internal_t*)pmppl->instance; pmp_internal_t* pmpi = (pmp_internal_t*)pmppl->pmp->instance; - return PMP_NOTIMPLIMENTED; - /* - if (ip2db_playlist_write(&pmppli->ip2db, filename, files, num_files, pmpi->env.path_to_root) != 0) { + if (ip3db_playlist_write(&pmppli->ip3db, filename, files, num_files, pmpi->env.path_to_root) != 0) { return PMPPLE_WRITE; } return 0; - */ } Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.vcproj =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.vcproj 2006-12-29 15:59:14 UTC (rev 229) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.vcproj 2006-12-31 07:38:06 UTC (rev 230) @@ -193,6 +193,10 @@ > </File> <File + RelativePath=".\playlist.c" + > + </File> + <File RelativePath=".\pmp_iriverplus3.c" > </File> Modified: trunk/pmplib/lib/pmp_iriverplus3/util.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/util.c 2006-12-29 15:59:14 UTC (rev 229) +++ trunk/pmplib/lib/pmp_iriverplus3/util.c 2006-12-31 07:38:06 UTC (rev 230) @@ -148,3 +148,24 @@ *ptr_size = size; return 0; } + +void filepath_slash(ucs2char_t* path) +{ + while (*path) { + if (*path == 0x005C) { + *path = 0x002F; + } + path++; + } +} + +void filepath_backslash(ucs2char_t* path) +{ + while (*path) { + if (*path == 0x002F) { + *path = 0x005C; + } + path++; + } +} + Modified: trunk/pmplib/lib/pmp_iriverplus3/util.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/util.h 2006-12-29 15:59:14 UTC (rev 229) +++ trunk/pmplib/lib/pmp_iriverplus3/util.h 2006-12-31 07:38:06 UTC (rev 230) @@ -35,4 +35,7 @@ int fread_all(FILE *fp, uint8_t** ptr_buffer, long* ptr_size); +void filepath_slash(ucs2char_t* path); +void filepath_backslash(ucs2char_t* path); + #endif/*__IP3DB_UTIL_H__*/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-01-17 19:24:48
|
Revision: 269 http://svn.sourceforge.net/pmplib/?rev=269&view=rev Author: nyaochi Date: 2007-01-17 11:24:46 -0800 (Wed, 17 Jan 2007) Log Message: ----------- Keep music records in pmp_music_internal_t structure. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/dat.h trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2007-01-17 18:38:14 UTC (rev 268) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2007-01-17 19:24:46 UTC (rev 269) @@ -624,7 +624,7 @@ return p ? p+1 : NULL; } -void dat_set(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records) +void dat_set(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records, const ip3db_playlist_t* playlists, int num_playlists) { /* Procedure: * 1) Construct the object chunk and attach music records with Object UIDs. @@ -659,7 +659,7 @@ static const ucs2char_t ucs2cs_root[] = {'/', 0}; dat_list_t* dato = &dat->objects; dat_list_t* datm = &dat->musics; - uint32_t num_objects = num_records; + uint32_t num_objects = num_records + num_playlists; object_record_t *objects = (object_record_t*)malloc(sizeof(object_record_t) * num_objects); dircache_t dc; @@ -680,12 +680,18 @@ dircache_push(&dc, ucs2cs_root, uid_root); /* Sort the records in alphabetical order of their path names. */ - for (i = 0;i < num_objects;++i) { + for (i = 0;i < num_records;++i) { objects[i].filepath = records[i][IP3DBF_MUSIC_FILEPATH].value.str; objects[i].filename = records[i][IP3DBF_MUSIC_FILENAME].value.str; objects[i].filetype = 2; objects[i].index = i; } + for (i = 0;i < num_playlists;++i) { + objects[i+num_records].filepath = playlists[i].filepath; + objects[i+num_records].filename = playlists[i].filename; + objects[i+num_records].filetype = 4; + objects[i+num_records].index = i; + } qsort(objects, num_objects, sizeof(objects[0]), comp_pathname); /* Loop for the records. */ @@ -737,6 +743,7 @@ /* Create a new object for the file name (FileType = 2). */ if (objects[i].filetype == 2) { + /* Music file. */ const ip3db_variant_t* record = records[objects[i].index]; uid = dato->num_entries; @@ -754,6 +761,17 @@ ip3db_variant_clone(&entry->fields[j], &record[j]); } ip3db_variant_set_dword(&entry->fields[IP3DBF_MUSIC_UID], uid); + } else if (objects[i].filetype == 4) { + /* Playlist file. */ + const ip3db_playlist_t* playlist = &playlists[objects[i].index]; + + uid = dato->num_entries; + entry = dat_list_expand(dato); + dat_entry_init(entry, &dic->objects); + ip3db_variant_set_dword(&entry->fields[IP3DBF_OBJECTS_UID], uid); + ip3db_variant_set_dword(&entry->fields[IP3DBF_OBJECTS_PARENTUID], puid); + ip3db_variant_set_word(&entry->fields[IP3DBF_OBJECTS_FILETYPE], 4); + ip3db_variant_set_str(&entry->fields[IP3DBF_OBJECTS_OBJECTNAME], file); } } Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.h 2007-01-17 18:38:14 UTC (rev 268) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.h 2007-01-17 19:24:46 UTC (rev 269) @@ -48,6 +48,6 @@ int dat_read(dat_t* dat, const dic_t* dic, FILE *fpi); int dat_write(dat_t* dat, dic_t* dic, FILE *fpo); void dat_dump(dat_t* dat, const dic_t* dic, FILE *fp); -void dat_set(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records); +void dat_set(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records, const ip3db_playlist_t* playlists, int num_playlists); #endif/*__IP3DB_DAT_H__*/ Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2007-01-17 18:38:14 UTC (rev 268) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2007-01-17 19:24:46 UTC (rev 269) @@ -213,10 +213,10 @@ return 0; } -result_t ip3db_set(ip3db_t* db, const ip3db_music_record_t* records, int num_records) +result_t ip3db_set(ip3db_t* db, const ip3db_music_record_t* records, int num_records, const ip3db_playlist_t* playlists, int num_playlists) { /* Construct records in db->dat from the records. */ - dat_set(db->dat, db->dic, records, num_records); + dat_set(db->dat, db->dic, records, num_records, playlists, num_playlists); return 0; } @@ -238,3 +238,12 @@ ip3db_variant_init(&var[i], db->dic->music.fields[i].type); } } + +void ip3db_record_finish(ip3db_t* db, ip3db_music_record_t* record) +{ + int i; + ip3db_variant_t* var = (ip3db_variant_t*)record; + for (i = 0;i < IP3DBF_MUSIC_LAST;++i) { + ip3db_variant_finish(&var[i]); + } +} Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2007-01-17 18:38:14 UTC (rev 268) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2007-01-17 19:24:46 UTC (rev 269) @@ -52,6 +52,11 @@ } value; } ip3db_variant_t; +typedef struct { + ucs2char_t* filepath; + ucs2char_t* filename; +} ip3db_playlist_t; + /** * Fields in a music record. */ @@ -180,7 +185,7 @@ void ip3db_finish(ip3db_t* db); result_t ip3db_read(ip3db_t* db, const ucs2char_t* datfn, const ucs2char_t* dicfn, const ucs2char_t* idxfn); result_t ip3db_write(ip3db_t* db, const ucs2char_t* datfn, const ucs2char_t* dicfn, const ucs2char_t* idxfn); -result_t ip3db_set(ip3db_t* db, const ip3db_music_record_t* records, int num_records); +result_t ip3db_set(ip3db_t* db, const ip3db_music_record_t* records, int num_records, const ip3db_playlist_t* playlists, int num_playlists); int ip3db_num_records(ip3db_t* db); ip3db_music_record_t* ip3db_get_record(ip3db_t* db, int i); result_t ip3db_dump(ip3db_t* db, FILE *fpo); @@ -193,5 +198,6 @@ ); void ip3db_record_init(ip3db_t* db, ip3db_music_record_t* record); +void ip3db_record_finish(ip3db_t* db, ip3db_music_record_t* record); #endif /*_IP3DB_IP3DB_H__*/ Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2007-01-17 18:38:14 UTC (rev 268) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2007-01-17 19:24:46 UTC (rev 269) @@ -89,6 +89,14 @@ const ip3model_descriptor_t* decl; } pmp_internal_t; +typedef struct { + ip3db_t ip3db; + ip3db_music_record_t* records; + int num_records; + ip3db_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); @@ -172,7 +180,7 @@ n++; } info->num_audio_extensions = n; - info->audio_extensions = (ucs2char_t*)ucs2malloc(sizeof(ucs2char_t*) * info->num_audio_extensions); + 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); } @@ -400,10 +408,10 @@ if (pmp->flag & PMPOF_MUSIC_DB_READ) { ucs2char_t dat[MAX_PATH], dic[MAX_PATH], idx[MAX_PATH]; - ip3db_t* ip3db = (ip3db_t*)pmp->music->instance; + pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)pmp->music->instance; set_filenames(dat, dic, idx, pmp); - return ip3db_read(ip3db, dat, dic, idx); + return ip3db_read(&pmpmi->ip3db, dat, dic, idx); } return 0; } @@ -413,19 +421,21 @@ result_t ret = 0; if (pmp->flag & PMPOF_MUSIC_DB_WRITE) { ucs2char_t dat[MAX_PATH], dic[MAX_PATH], idx[MAX_PATH]; - ip3db_t* ip3db = (ip3db_t*)pmp->music->instance; + pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)pmp->music->instance; + ip3db_set(&pmpmi->ip3db, pmpmi->records, pmpmi->num_records, pmpmi->playlists, pmpmi->num_playlists); + set_filenames(dat, dic, idx, pmp); - return ip3db_write(ip3db, dat, dic, idx); + return ip3db_write(&pmpmi->ip3db, dat, dic, idx); } return 0; } 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_music_internal_t* pmpmi = NULL; *ptr_music = 0; @@ -434,19 +444,19 @@ return PMPDBE_OUTOFMEMORY; } - ip3db = calloc(1, sizeof(ip3db_t)); - if (!ip3db) { + pmpmi = calloc(1, sizeof(pmp_music_internal_t)); + if (!pmpmi) { free(music); return PMPDBE_OUTOFMEMORY; } - ip3db_init(ip3db); + ip3db_init(&pmpmi->ip3db); 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; + music->instance = pmpmi; *ptr_music = music; return 0; @@ -456,12 +466,14 @@ -static uint32_t pmpmusic_release(pmp_music_t* pmpmusic) +static uint32_t pmpmusic_release(pmp_music_t* music) { - ip3db_t* ip3db = (ip3db_t*)pmpmusic->instance; - ip3db_finish(ip3db); - free(pmpmusic->instance); - free(pmpmusic); + pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance; + ip3db_finish(&pmpmi->ip3db); + free(pmpmi->records); + free(pmpmi->playlists); + free(pmpmi); + free(music); return 0; } @@ -479,15 +491,24 @@ { 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); + pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)pmpdb->instance; + /* Free records attached to pmpmi. */ + for (i = 0;i < (uint32_t)pmpmi->num_records;++i) { + ip3db_record_finish(&pmpmi->ip3db, &pmpmi->records[i]); + } + free(pmpmi->records); + + /* Allocate new records. */ + pmpmi->records = (ip3db_music_record_t*)malloc(sizeof(ip3db_music_record_t) * num_records); + pmpmi->num_records = num_records; + for (i = 0;i < num_records;++i) { const pmp_music_record_t* src = &records[i]; - ip3db_variant_t* dst = array[i]; + ip3db_variant_t* dst = pmpmi->records[i]; - ip3db_record_init(ip3db, &array[i]); + ip3db_record_init(&pmpmi->ip3db, &pmpmi->records[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); @@ -516,18 +537,16 @@ ip3db_variant_set_dword(&dst[IP3DBF_MUSIC_UID], (uint32_t)i+1); } - ip3db_set(ip3db, array, num_records); - free(array); return 0; } static result_t pmpmusic_get_records(pmp_music_t* pmpdb, pmp_music_record_t* records, uint32_t* num_records) { pmp_t* pmp = pmpdb->pmp; - ip3db_t* ip3db = (ip3db_t*)pmpdb->instance; pmp_internal_t* pmpi = (pmp_internal_t*)pmpdb->pmp->instance; + pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)pmpdb->instance; ucs2char_t *path_to_root = alloca(sizeof(ucs2char_t) * (ucs2len(pmp->info.path_to_root)+1)); - int i, n = ip3db_num_records(ip3db); + int i, n = ip3db_num_records(&pmpmi->ip3db); if (!records) { *num_records = (uint32_t)n; @@ -535,7 +554,7 @@ } for (i = 0;i < n;++i) { - const ip3db_variant_t* src = (const ip3db_variant_t*)ip3db_get_record(ip3db, i); + const ip3db_variant_t* src = (const ip3db_variant_t*)ip3db_get_record(&pmpmi->ip3db, i); pmp_music_record_t* dst = &records[i]; size_t length = 0; @@ -575,14 +594,14 @@ return 0; } -static result_t pmpmusic_dump(pmp_music_t* pmpmusic, FILE *fp, int level) +static result_t pmpmusic_dump(pmp_music_t* music, FILE *fp, int level) { - ip3db_t* ip3db = (ip3db_t*)pmpmusic->instance; + pmp_music_internal_t* pmpmi = (pmp_music_internal_t*)music->instance; if (level > 0) { return PMP_NOTIMPLIMENTED; //return ip2db_repr(&pmpdbi->ip2db, fp); } else { - return ip3db_dump(ip3db, fp); + return ip3db_dump(&pmpmi->ip3db, fp); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-01-18 17:34:30
|
Revision: 271 http://svn.sourceforge.net/pmplib/?rev=271&view=rev Author: nyaochi Date: 2007-01-18 09:34:30 -0800 (Thu, 18 Jan 2007) Log Message: ----------- Experimental code for generating iriver E10 playlists. Playlists for iriver E10 are actually stored in the database: *.plp files are found to be dummy. Although I had to change a DWORD value in db.dic, the playlists worked on my player. I still need to improve dic.c and dat.c to handle large number of files. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/dat.h trunk/pmplib/lib/pmp_iriverplus3/dic.c trunk/pmplib/lib/pmp_iriverplus3/dic.h trunk/pmplib/lib/pmp_iriverplus3/idx.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2007-01-18 15:06:25 UTC (rev 270) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2007-01-18 17:34:30 UTC (rev 271) @@ -452,6 +452,12 @@ } } + /* Read Music page(s) */ + dat_list_read(&dat->references, &ph, &dic->references, buffer, PAGESIZE * 2); + while (ph.next_page) { + dat_list_read(&dat->references, &ph, &dic->references, buffer, PAGESIZE * (ph.next_page - 1)); + } + free(buffer); return 0; } @@ -460,7 +466,7 @@ { uint32_t i = 0; page_header_t ph; - long buffer_size = PAGESIZE * 2; + long buffer_size = PAGESIZE * 3; uint8_t* buffer = (uint8_t*)calloc(buffer_size, sizeof(uint8_t)); if (!buffer) { @@ -506,6 +512,23 @@ dic->header.num_dat_pages += 1; } + /* Write References page(s) */ + i = 0; + memset(&ph, 0, sizeof(ph)); + ph.next_page = dic->header.num_dat_pages + 2; + dat_list_write(&dat->references, i, &ph, buffer, PAGESIZE * 2); + dic->header.num_dat_pages += 1; + while (ph.next_page) { + uint32_t page = ph.next_page++; + buffer_size = PAGESIZE * page; + buffer = (uint8_t*)realloc(buffer, sizeof(uint8_t) * buffer_size); + memset(buffer + PAGESIZE * (page - 1), 0, PAGESIZE); + i += ph.num_entries; + dat_list_write(&dat->references, i, &ph, buffer, PAGESIZE * (page - 1)); + dic->header.num_dat_pages += 1; + } + + if (fwrite(buffer, 1, buffer_size, fpo) != buffer_size) { free(buffer); return 1; @@ -524,10 +547,39 @@ fprintf(fp, "MUSIC = {\n"); dat_list_dump(&dat->musics, &dic->music, fp); fprintf(fp, "}\n"); + fprintf(fp, "REFERENCES = {\n"); + dat_list_dump(&dat->references, &dic->references, fp); + fprintf(fp, "}\n"); } +static uint32_t findfile(dat_t* dat, const ucs2char_t *filename) +{ + int i; + const ucs2char_t *filepart = NULL; + ucs2char_t *pathname = alloca(sizeof(ucs2char_t) * (ucs2len(filename) + 1)); + + filepart = ucs2rchr(filename, '/'); + if (!filepart) { + filepart = filename; + } else { + filepart++; + } + + ucs2ncpy(pathname, filename, (filepart-filename)); + pathname[filepart-filename] = 0; + + for (i = 0;i < dat->musics.num_entries;++i) { + dat_entry_t* entry = &dat->musics.entries[i]; + if (ucs2icmp(entry->fields[IP3DBF_MUSIC_FILENAME].value.str, filepart) == 0 && + ucs2icmp(entry->fields[IP3DBF_MUSIC_FILEPATH].value.str, pathname) == 0) { + return entry->fields[IP3DBF_MUSIC_UID].value.dword; + } + } + return 0; +} + typedef struct { ucs2char_t* path; uint32_t uid; @@ -624,7 +676,7 @@ return p ? p+1 : NULL; } -void dat_set(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records, const ip3db_playlist_t* playlists, int num_playlists) +void dat_set(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records, ip3db_playlist_t* playlists, int num_playlists) { /* Procedure: * 1) Construct the object chunk and attach music records with Object UIDs. @@ -659,6 +711,7 @@ static const ucs2char_t ucs2cs_root[] = {'/', 0}; dat_list_t* dato = &dat->objects; dat_list_t* datm = &dat->musics; + dat_list_t* datr = &dat->references; uint32_t num_objects = num_records + num_playlists; object_record_t *objects = (object_record_t*)malloc(sizeof(object_record_t) * num_objects); dircache_t dc; @@ -668,6 +721,7 @@ /* Clear all entries. */ dat_list_finish(dato); dat_list_finish(datm); + dat_list_finish(datr); dat_uidmap_finish(dat->objects_uidmap); /* Append an entry for the root directory. */ @@ -763,18 +817,31 @@ ip3db_variant_set_dword(&entry->fields[IP3DBF_MUSIC_UID], uid); } else if (objects[i].filetype == 4) { /* Playlist file. */ - const ip3db_playlist_t* playlist = &playlists[objects[i].index]; + ip3db_playlist_t* pl = &playlists[objects[i].index]; - uid = dato->num_entries; + pl->uid = dato->num_entries; entry = dat_list_expand(dato); dat_entry_init(entry, &dic->objects); - ip3db_variant_set_dword(&entry->fields[IP3DBF_OBJECTS_UID], uid); + ip3db_variant_set_dword(&entry->fields[IP3DBF_OBJECTS_UID], pl->uid); ip3db_variant_set_dword(&entry->fields[IP3DBF_OBJECTS_PARENTUID], puid); ip3db_variant_set_word(&entry->fields[IP3DBF_OBJECTS_FILETYPE], 4); ip3db_variant_set_str(&entry->fields[IP3DBF_OBJECTS_OBJECTNAME], file); } } + /* Loop for playlists. */ + for (i = 0;i < num_playlists;++i) { + const ip3db_playlist_t* pl = &playlists[i]; + for (j = 0;j < pl->num_entries;++j) { + entry = dat_list_expand(datr); + dat_entry_init(entry, &dic->references); + + ip3db_variant_set_dword(&entry->fields[IP3DBF_REFERENCES_PARENTCLUSTER], pl->uid); + ip3db_variant_set_dword(&entry->fields[IP3DBF_REFERENCES_CHILDCLUSTER], findfile(dat, pl->entries[j])); + ip3db_variant_set_word(&entry->fields[IP3DBF_REFERENCES_FILEFORMAT], 0x3009); + } + } + dircache_finish(&dc); dat->objects_uidmap = dat_uidmap_create(&dat->objects); Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.h 2007-01-18 15:06:25 UTC (rev 270) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.h 2007-01-18 17:34:30 UTC (rev 271) @@ -40,6 +40,7 @@ struct tag_dat_t { dat_list_t objects; dat_list_t musics; + dat_list_t references; sort_index_t* objects_uidmap; }; @@ -48,6 +49,6 @@ int dat_read(dat_t* dat, const dic_t* dic, FILE *fpi); int dat_write(dat_t* dat, dic_t* dic, FILE *fpo); void dat_dump(dat_t* dat, const dic_t* dic, FILE *fp); -void dat_set(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records, const ip3db_playlist_t* playlists, int num_playlists); +void dat_set(dat_t* dat, dic_t* dic, const ip3db_music_record_t* records, int num_records, ip3db_playlist_t* playlists, int num_playlists); #endif/*__IP3DB_DAT_H__*/ Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.c 2007-01-18 15:06:25 UTC (rev 270) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.c 2007-01-18 17:34:30 UTC (rev 271) @@ -57,6 +57,11 @@ {0, 0x043E, {IP3DBF_MUSIC_ALBUM, IP3DBF_MUSIC_TRACKNUMBER, IP3DBF_MUSIC_NONE}}, }; +static dic_index_t references_indices[] = { + {0, 0x0764, {IP3DBF_REFERENCES_PARENTCLUSTER, IP3DBF_REFERENCES_NONE, IP3DBF_REFERENCES_NONE}}, + {0, 0x078C, {IP3DBF_REFERENCES_CHILDCLUSTER, IP3DBF_REFERENCES_NONE, IP3DBF_REFERENCES_NONE}}, +}; + static dic_index_t objects_indices[] = { {0, 0x099A, {IP3DBF_OBJECTS_UID, IP3DBF_MUSIC_NONE, IP3DBF_MUSIC_NONE}}, {0, 0x09F0, {IP3DBF_OBJECTS_FILETYPE, IP3DBF_MUSIC_NONE, IP3DBF_MUSIC_NONE}}, @@ -138,6 +143,11 @@ dic->music.fields = (dic_field_t*)calloc(dic->music.num_fields, sizeof(dic_field_t)); dic->music.num_indices = sizeof(music_indices) / sizeof(music_indices[0]); dic->music.indices = music_indices; + dic_table_init(&dic->references); + dic->references.num_fields = IP3DBF_REFERENCES_LAST; + dic->references.fields = (dic_field_t*)calloc(dic->references.num_fields, sizeof(dic_field_t)); + dic->references.num_indices = sizeof(references_indices) / sizeof(references_indices[0]); + dic->references.indices = references_indices; dic_table_init(&dic->objects); dic->objects.num_fields = IP3DBF_OBJECTS_LAST; dic->objects.fields = (dic_field_t*)calloc(dic->objects.num_fields, sizeof(dic_field_t)); @@ -159,6 +169,7 @@ { if (dic) { dic_table_finish(&dic->music); + dic_table_finish(&dic->references); dic_table_finish(&dic->objects); free(dic->buffer); free(dic); @@ -207,6 +218,12 @@ next = dic->music.fields[i].next; } + next = 0x00000764; + for (i = 0;i < dic->references.num_fields;++i) { + dic_field_serialize(buffer + next, &dic->references.fields[i], is_storing); + next = dic->references.fields[i].next; + } + next = 0x0000099A; for (i = 0;i < dic->objects.num_fields;++i) { dic_field_serialize(buffer + next, &dic->objects.fields[i], is_storing); @@ -218,6 +235,11 @@ serialize_uint32be(buffer + offset, &dic->music.indices[i].idx_root, is_storing); } + for (i = 0;i < dic->references.num_indices;++i) { + uint32_t offset = dic->references.indices[i].offset + sizeof(uint32_t) * 2; + serialize_uint32be(buffer + offset, &dic->references.indices[i].idx_root, is_storing); + } + for (i = 0;i < dic->objects.num_indices;++i) { uint32_t offset = dic->objects.indices[i].offset + sizeof(uint32_t) * 2; serialize_uint32be(buffer + offset, &dic->objects.indices[i].idx_root, is_storing); @@ -231,8 +253,13 @@ fprintf(fp, "===== db.dic =====\n"); fprintf(fp, "MUSIC = {\n"); dic_table_dump(&dic->music, fp); + fprintf(fp, "}\n"); + fprintf(fp, "REFERENCES = {\n"); + dic_table_dump(&dic->references, fp); + fprintf(fp, "}\n"); fprintf(fp, "OBJECTS = {\n"); dic_table_dump(&dic->objects, fp); + fprintf(fp, "}\n"); fprintf(fp, "\n"); } @@ -243,6 +270,9 @@ case IP3DBIDX_MUSIC: indices = dic->music.indices; break; + case IP3DBIDX_REFERENCES: + indices = dic->references.indices; + break; case IP3DBIDX_OBJECTS: indices = dic->objects.indices; break; @@ -261,6 +291,9 @@ case IP3DBIDX_MUSIC: indices = dic->music.indices; break; + case IP3DBIDX_REFERENCES: + indices = dic->references.indices; + break; case IP3DBIDX_OBJECTS: indices = dic->objects.indices; break; @@ -280,6 +313,9 @@ case IP3DBIDX_MUSIC: tbl = &dic->music; break; + case IP3DBIDX_REFERENCES: + tbl = &dic->references; + break; case IP3DBIDX_OBJECTS: tbl = &dic->objects; break; Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.h 2007-01-18 15:06:25 UTC (rev 270) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.h 2007-01-18 17:34:30 UTC (rev 271) @@ -54,6 +54,7 @@ struct tag_dic_t { dic_header_t header; dic_table_t music; + dic_table_t references; dic_table_t objects; uint8_t* buffer; Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2007-01-18 15:06:25 UTC (rev 270) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2007-01-18 17:34:30 UTC (rev 271) @@ -700,11 +700,21 @@ /* Convert the byte order of values in AVL trees. */ for (i = 0;i < dic->music.num_indices;++i) { uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_MUSIC, i); - from_be_avltree(idx->avl, idx_root, &dic->music, i, 0); + if (idx_root) { + from_be_avltree(idx->avl, idx_root, &dic->music, i, 0); + } } + for (i = 0;i < dic->references.num_indices;++i) { + uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_REFERENCES, i); + if (idx_root) { + from_be_avltree(idx->avl, idx_root, &dic->references, i, 0); + } + } for (i = 0;i < dic->objects.num_indices;++i) { uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_OBJECTS, i); - from_be_avltree(idx->avl, idx_root, &dic->objects, i, 0); + if (idx_root) { + from_be_avltree(idx->avl, idx_root, &dic->objects, i, 0); + } } return 0; } @@ -728,6 +738,10 @@ uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_MUSIC, i); to_be_avltree(idx->avl, idx_root, &dic->music, i, 0); } + for (i = 0;i < dic->references.num_indices;++i) { + uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_REFERENCES, i); + to_be_avltree(idx->avl, idx_root, &dic->references, i, 0); + } for (i = 0;i < dic->objects.num_indices;++i) { uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_OBJECTS, i); to_be_avltree(idx->avl, idx_root, &dic->objects, i, 0); @@ -756,6 +770,15 @@ fprintf(fpo, "]\n"); avl_dump(idx->avl, idx_root, &dic->music, i, 0, fpo); } + for (i = 0;i < dic->references.num_indices;++i) { + uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_REFERENCES, i); + fprintf(fpo, "["); + dic_repr_index(dic, IP3DBIDX_REFERENCES, i, fpo); + fprintf(fpo, "]\n"); + if (idx_root) { + avl_dump(idx->avl, idx_root, &dic->references, i, 0, fpo); + } + } for (i = 0;i < dic->objects.num_indices;++i) { uint32_t idx_root = dic_get_idxroot(dic, IP3DBIDX_OBJECTS, i); fprintf(fpo, "["); @@ -822,6 +845,12 @@ dic_set_idxroot(dic, IP3DBIDX_MUSIC, index, root); } + for (index = 0;index < dic->references.num_indices;++index) { + uint32_t root = 0; + idx_construct_index(idx, &dic->references, &dat->references, &root, index); + dic_set_idxroot(dic, IP3DBIDX_REFERENCES, index, root); + } + for (index = 0;index < dic->objects.num_indices;++index) { uint32_t root = 0; idx_construct_index(idx, &dic->objects, &dat->objects, &root, index); Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2007-01-18 15:06:25 UTC (rev 270) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2007-01-18 17:34:30 UTC (rev 271) @@ -57,6 +57,7 @@ ucs2char_t* filename; int num_entries; ucs2char_t **entries; + uint32_t uid; } ip3db_playlist_t; /** @@ -94,6 +95,15 @@ IP3DBF_MUSIC_LAST, }; +enum { + IP3DBF_REFERENCES_NONE = -1, + IP3DBF_REFERENCES_BEGIN = 0, + IP3DBF_REFERENCES_PARENTCLUSTER = 0, + IP3DBF_REFERENCES_CHILDCLUSTER, + IP3DBF_REFERENCES_FILEFORMAT, + IP3DBF_REFERENCES_LAST, +}; + /** * A music record. */ @@ -125,6 +135,7 @@ enum { IP3DBIDX_NONE = -1, IP3DBIDX_MUSIC = 0, + IP3DBIDX_REFERENCES, IP3DBIDX_OBJECTS, IP3DBIDX_LAST, }; @@ -150,6 +161,14 @@ IP3DBIDX_MUSIC_LAST, }; +enum { + IP3DBIDX_REFERENCES_NONE = -1, + IP3DBIDX_REFERENCES_BEGIN = 0, + IP3DBIDX_REFERENCES_PARENTCLUSTER = 0, + IP3DBIDX_REFERENCES_CHILDCLUSTER, + IP3DBIDX_REFERENCES_LAST, +}; + /** * Indices for the object chunk. */ Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2007-01-18 15:06:25 UTC (rev 270) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2007-01-18 17:34:30 UTC (rev 271) @@ -652,7 +652,11 @@ dst->num_entries = src->num_entries; dst->entries = (ucs2char_t**)ucs2malloc(sizeof(ucs2char_t*) * src->num_entries); for (j = 0;j < src->num_entries;++j) { - dst->entries[j] = ucs2dup(src->entries[j]); + ucs2char_t filename[MAX_PATH]; + + ucs2cpy(filename, filepath_skipdrive(src->entries[j], music->pmp->info.path_to_root)); + filepath_slash(filename); + dst->entries[j] = ucs2dup(filename); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-01-18 19:44:37
|
Revision: 272 http://svn.sourceforge.net/pmplib/?rev=272&view=rev Author: nyaochi Date: 2007-01-18 11:44:24 -0800 (Thu, 18 Jan 2007) Log Message: ----------- Improved page handling for db.dat. This revision is not stable yet, but it could generate multiple continuous Object pages successfully. Although this revision does not work without a playlist, my time is up. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/dat.c trunk/pmplib/lib/pmp_iriverplus3/dic.c trunk/pmplib/lib/pmp_iriverplus3/dic.h trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c Modified: trunk/pmplib/lib/pmp_iriverplus3/dat.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dat.c 2007-01-18 17:34:30 UTC (rev 271) +++ trunk/pmplib/lib/pmp_iriverplus3/dat.c 2007-01-18 19:44:24 UTC (rev 272) @@ -377,7 +377,7 @@ int dat_read(dat_t* dat, const dic_t* dic, FILE *fpi) { - uint32_t i = 0; + uint32_t i = 0, page = 0; page_header_t ph; long buffer_size = 0; uint8_t* buffer = NULL; @@ -392,9 +392,10 @@ dat_list_finish(&dat->objects); /* Read Objects page(s) */ - dat_list_read(&dat->objects, &ph, &dic->objects, buffer, PAGESIZE * 0); - while (ph.next_page) { - dat_list_read(&dat->objects, &ph, &dic->objects, buffer, PAGESIZE * (ph.next_page - 1)); + page = dic->objects.dat_page; + while (page) { + dat_list_read(&dat->objects, &ph, &dic->objects, buffer, PAGESIZE * (page - 1)); + page = ph.next_page; } /* Construct Object UID -> dat->objects[i] mapping table. */ @@ -405,9 +406,10 @@ dat_list_finish(&dat->musics); /* Read Music page(s) */ - dat_list_read(&dat->musics, &ph, &dic->music, buffer, PAGESIZE * 1); - while (ph.next_page) { - dat_list_read(&dat->musics, &ph, &dic->music, buffer, PAGESIZE * (ph.next_page - 1)); + page = dic->music.dat_page; + while (page) { + dat_list_read(&dat->musics, &ph, &dic->music, buffer, PAGESIZE * (page - 1)); + page = ph.next_page; } /* Set filename and pathname fields. */ @@ -452,10 +454,11 @@ } } - /* Read Music page(s) */ - dat_list_read(&dat->references, &ph, &dic->references, buffer, PAGESIZE * 2); - while (ph.next_page) { - dat_list_read(&dat->references, &ph, &dic->references, buffer, PAGESIZE * (ph.next_page - 1)); + /* Read References page(s) */ + page = dic->references.dat_page; + while (page) { + dat_list_read(&dat->references, &ph, &dic->references, buffer, PAGESIZE * (page - 1)); + page = ph.next_page; } free(buffer); @@ -464,29 +467,29 @@ int dat_write(dat_t* dat, dic_t* dic, FILE *fpo) { - uint32_t i = 0; + uint32_t i = 0, page = 0; page_header_t ph; - long buffer_size = PAGESIZE * 3; - uint8_t* buffer = (uint8_t*)calloc(buffer_size, sizeof(uint8_t)); + long buffer_size = 0; + uint8_t* buffer = NULL; - if (!buffer) { - return 1; - } + dic->header.num_dat_pages = 0; + memset(&ph, 0, sizeof(ph)); + /* Write Objects page(s) */ i = 0; - memset(&ph, 0, sizeof(ph)); - ph.next_page = 3; - dat_list_write(&dat->objects, i, &ph, buffer, PAGESIZE * 0); - dic->header.num_dat_pages = 1; - while (ph.next_page) { - uint32_t page = ph.next_page++; + dic->objects.dat_page = page = (dic->header.num_dat_pages + 1); + while (page) { buffer_size = PAGESIZE * page; buffer = (uint8_t*)realloc(buffer, sizeof(uint8_t) * buffer_size); memset(buffer + PAGESIZE * (page - 1), 0, PAGESIZE); + + ph.next_page = page + 1; + dat_list_write(&dat->objects, i, &ph, buffer, PAGESIZE * (page - 1)); + i += ph.num_entries; - dat_list_write(&dat->objects, i, &ph, buffer, PAGESIZE * (page - 1)); dic->header.num_dat_pages += 1; + page = ph.next_page; } /* Clear filepath and filename */ @@ -499,36 +502,36 @@ /* Write Music page(s) */ i = 0; - ph.next_page = dic->header.num_dat_pages + 2; - dat_list_write(&dat->musics, i, &ph, buffer, PAGESIZE * 1); - dic->header.num_dat_pages += 1; - while (ph.next_page) { - uint32_t page = ph.next_page++; + dic->music.dat_page = page = (dic->header.num_dat_pages+1); + while (page) { buffer_size = PAGESIZE * page; buffer = (uint8_t*)realloc(buffer, sizeof(uint8_t) * buffer_size); memset(buffer + PAGESIZE * (page - 1), 0, PAGESIZE); + + ph.next_page = page + 1; + dat_list_write(&dat->musics, i, &ph, buffer, PAGESIZE * (page - 1)); + i += ph.num_entries; - dat_list_write(&dat->musics, i, &ph, buffer, PAGESIZE * (page - 1)); dic->header.num_dat_pages += 1; + page = ph.next_page; } /* Write References page(s) */ i = 0; - memset(&ph, 0, sizeof(ph)); - ph.next_page = dic->header.num_dat_pages + 2; - dat_list_write(&dat->references, i, &ph, buffer, PAGESIZE * 2); - dic->header.num_dat_pages += 1; - while (ph.next_page) { - uint32_t page = ph.next_page++; + dic->references.dat_page = page = (dic->header.num_dat_pages+1); + while (page) { buffer_size = PAGESIZE * page; buffer = (uint8_t*)realloc(buffer, sizeof(uint8_t) * buffer_size); memset(buffer + PAGESIZE * (page - 1), 0, PAGESIZE); + + ph.next_page = page + 1; + dat_list_write(&dat->references, i, &ph, buffer, PAGESIZE * (page - 1)); + i += ph.num_entries; - dat_list_write(&dat->references, i, &ph, buffer, PAGESIZE * (page - 1)); dic->header.num_dat_pages += 1; + page = ph.next_page; } - if (fwrite(buffer, 1, buffer_size, fpo) != buffer_size) { free(buffer); return 1; Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.c 2007-01-18 17:34:30 UTC (rev 271) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.c 2007-01-18 19:44:24 UTC (rev 272) @@ -117,22 +117,65 @@ for (i = 0;i < list->num_fields;++i) { dic_field_finish(&list->fields[i]); } + free(list->name); free(list->fields); } static void dic_table_dump(dic_table_t* list, FILE *fp) { int i; + + fprints(fp, "%s = {\n", list->name); + fprintf(fp, " unknown0: 0x%08X\n", list->unknown0); + fprintf(fp, " next: 0x%08X\n", list->next); + fprintf(fp, " unknown1: 0x%08X\n", list->unknown1); + fprintf(fp, " dat_page: 0x%08X\n", list->dat_page); + fprintf(fp, " offset_fields: 0x%08X\n", list->offset_fields); + fprintf(fp, " offset_indices: 0x%08X\n", list->offset_indices); + for (i = 0;i < list->num_fields;++i) { const dic_field_t* entry = &list->fields[i]; fprintf(fp, " FIELD %d = {\n", i); dic_field_dump(entry, fp); fprintf(fp, " }\n"); } + + fprintf(fp, "}\n"); } +static size_t dic_table_serialize(uint8_t* buffer, uint32_t start, dic_table_t* list, int is_storing) +{ + uint32_t i, next; + uint8_t *p = buffer + start; + p += serialize_uint32be(p, &list->unknown0, is_storing); + p += serialize_uint32be(p, &list->next, is_storing); + p += serialize_uint32be(p, &list->unknown1, is_storing); + p += serialize_uint32be(p, &list->dat_page, is_storing); + p += serialize_uint32be(p, &list->offset_fields, is_storing); + p += serialize_uint32be(p, &list->offset_indices, is_storing); + if (is_storing) { + p += (serialize_ucs2be_string_var(p, list->name, is_storing) + 1) * sizeof(ucs2char_t); + } else { + p += (serialize_ucs2be_string_var_alloc(p, &list->name) + 1) * sizeof(ucs2char_t); + } + next = list->offset_fields; + for (i = 0;i < list->num_fields;++i) { + dic_field_serialize(buffer + next, &list->fields[i], is_storing); + next = list->fields[i].next; + } + + for (i = 0;i < list->num_indices;++i) { + uint32_t offset = list->indices[i].offset + sizeof(uint32_t) * 2; + serialize_uint32be(buffer + offset, &list->indices[i].idx_root, is_storing); + } + + return (size_t)(p - (buffer + start)); +} + + + dic_t* dic_new() { uint8_t* dic_template = NULL; @@ -203,7 +246,6 @@ static int dic_serialize(dic_t* dic, uint8_t* buffer, int is_storing) { - int i; uint32_t next = 0; uint8_t* p = buffer; @@ -212,54 +254,19 @@ p += serialize_uint32be(p, &dic->header.num_idx_pages, is_storing); p += serialize_uint32be(p, &dic->header.unknown1, is_storing); - next = 0x0000003C; - for (i = 0;i < dic->music.num_fields;++i) { - dic_field_serialize(buffer + next, &dic->music.fields[i], is_storing); - next = dic->music.fields[i].next; - } + dic_table_serialize(buffer, 0x0018, &dic->music, is_storing); + dic_table_serialize(buffer, 0x0736, &dic->references, is_storing); + dic_table_serialize(buffer, 0x0972, &dic->objects, is_storing); - next = 0x00000764; - for (i = 0;i < dic->references.num_fields;++i) { - dic_field_serialize(buffer + next, &dic->references.fields[i], is_storing); - next = dic->references.fields[i].next; - } - - next = 0x0000099A; - for (i = 0;i < dic->objects.num_fields;++i) { - dic_field_serialize(buffer + next, &dic->objects.fields[i], is_storing); - next = dic->objects.fields[i].next; - } - - for (i = 0;i < dic->music.num_indices;++i) { - uint32_t offset = dic->music.indices[i].offset + sizeof(uint32_t) * 2; - serialize_uint32be(buffer + offset, &dic->music.indices[i].idx_root, is_storing); - } - - for (i = 0;i < dic->references.num_indices;++i) { - uint32_t offset = dic->references.indices[i].offset + sizeof(uint32_t) * 2; - serialize_uint32be(buffer + offset, &dic->references.indices[i].idx_root, is_storing); - } - - for (i = 0;i < dic->objects.num_indices;++i) { - uint32_t offset = dic->objects.indices[i].offset + sizeof(uint32_t) * 2; - serialize_uint32be(buffer + offset, &dic->objects.indices[i].idx_root, is_storing); - } - return 0; } void dic_dump(dic_t* dic, FILE *fp) { fprintf(fp, "===== db.dic =====\n"); - fprintf(fp, "MUSIC = {\n"); dic_table_dump(&dic->music, fp); - fprintf(fp, "}\n"); - fprintf(fp, "REFERENCES = {\n"); dic_table_dump(&dic->references, fp); - fprintf(fp, "}\n"); - fprintf(fp, "OBJECTS = {\n"); dic_table_dump(&dic->objects, fp); - fprintf(fp, "}\n"); fprintf(fp, "\n"); } Modified: trunk/pmplib/lib/pmp_iriverplus3/dic.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/dic.h 2007-01-18 17:34:30 UTC (rev 271) +++ trunk/pmplib/lib/pmp_iriverplus3/dic.h 2007-01-18 19:44:24 UTC (rev 272) @@ -45,6 +45,14 @@ } dic_index_t; typedef struct { + uint32_t unknown0; + uint32_t next; + uint32_t unknown1; + uint32_t dat_page; + uint32_t offset_fields; + uint32_t offset_indices; + ucs2char_t* name; + int num_fields; dic_field_t *fields; int num_indices; Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2007-01-18 17:34:30 UTC (rev 271) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2007-01-18 19:44:24 UTC (rev 272) @@ -71,7 +71,7 @@ "System\\E10.SYS", "System\\db.dat", "System\\db.dic", "System\\db.idx", ".mp3\0.ogg\0.wma\0.wav\0", {PMPCODEC_MPEGLAYER3, PMPCODEC_VORBIS, PMPCODEC_WMA, PMPCODEC_WAV, 0, 0, 0, 0}, - "System\\", "Music2\\", "Playlists\\", + "System\\", "", "Playlists\\", ".plp", }, { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ny...@us...> - 2007-01-24 10:26:46
|
Revision: 273 http://svn.sourceforge.net/pmplib/?rev=273&view=rev Author: nyaochi Date: 2007-01-24 02:26:45 -0800 (Wed, 24 Jan 2007) Log Message: ----------- Removed the generation routine for *.plp files from pmp_iriverplus3 since it's unnecessary. Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/ip3db.h trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.vcproj Removed Paths: ------------- trunk/pmplib/lib/pmp_iriverplus3/plp.c Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2007-01-18 19:44:24 UTC (rev 272) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2007-01-24 10:26:45 UTC (rev 273) @@ -278,22 +278,3 @@ dst->entries[i] = ucs2dup(src->entries[i]); } } - -int ip3db_write_playlists(ip3db_t* db, const ip3db_playlist_t* playlists, int num_playlists, const ucs2char_t *path_to_root) -{ - int i; - - for (i = 0;i < num_playlists;++i) { - ucs2char_t filename[MAX_PATH]; - const ip3db_playlist_t* pl = &playlists[i]; - - ucs2cpy(filename, path_to_root); - ucs2cat(filename, pl->filepath + 1); - ucs2cat(filename, pl->filename); - filepath_backslash(filename); - - plp_write(db, filename, pl->entries, pl->num_entries, path_to_root); - } - - return 0; -} Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.h =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2007-01-18 19:44:24 UTC (rev 272) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.h 2007-01-24 10:26:45 UTC (rev 273) @@ -211,8 +211,6 @@ ip3db_music_record_t* ip3db_get_record(ip3db_t* db, int i); result_t ip3db_dump(ip3db_t* db, FILE *fpo); -int ip3db_write_playlists(ip3db_t* db, const ip3db_playlist_t* playlists, int num_playlists, const ucs2char_t *path_to_root); - void ip3db_record_init(ip3db_t* db, ip3db_music_record_t* record); void ip3db_record_finish(ip3db_t* db, ip3db_music_record_t* record); Deleted: trunk/pmplib/lib/pmp_iriverplus3/plp.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/plp.c 2007-01-18 19:44:24 UTC (rev 272) +++ trunk/pmplib/lib/pmp_iriverplus3/plp.c 2007-01-24 10:26:45 UTC (rev 273) @@ -1,120 +0,0 @@ -/* - * Playlist reader/writer for iriver E10. - * - * Copyright (c) 2005-2006 Nyaochi - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -/* $Id$ */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif/*HAVE_CONFIG_H*/ - -#include <os.h> -#include <stdio.h> -#include <stdlib.h> -#include <ucs2char.h> -#include <filepath.h> - -#include "serialize.h" -#include "util.h" -#include "ip3db.h" -#include "dat.h" - -static uint32_t findfile(ip3db_t* db, const ucs2char_t *filename, const ucs2char_t *path_to_root) -{ - int i; - const ucs2char_t *filepart = filepath_skippath(filename); - const ucs2char_t *pathfile = filepath_skipdrive(filename, path_to_root); - ucs2char_t *pathname = alloca(sizeof(ucs2char_t) * (ucs2len(pathfile) + 1)); - - ucs2cpy(pathname, pathfile); - filepath_remove_filespec(pathname); - filepath_addslash(pathname); - filepath_slash(pathname); - - for (i = 0;i < db->dat->musics.num_entries;++i) { - dat_entry_t* entry = &db->dat->musics.entries[i]; - if (ucs2icmp(entry->fields[IP3DBF_MUSIC_FILENAME].value.str, filepart) == 0 && - ucs2icmp(entry->fields[IP3DBF_MUSIC_FILEPATH].value.str, pathname) == 0) { - return entry->fields[IP3DBF_MUSIC_UID].value.dword; - } - } - return 0; -} - -int plp_write( - ip3db_t* db, - const ucs2char_t *filename, - ucs2char_t* const mediafiles[], - int num_mediafiles, - const ucs2char_t *path_to_root - ) -{ - int i; - FILE *fp = NULL; - uint32_t* uids = NULL; - uint32_t num_uids = 0; - - for (i = 0;i < num_mediafiles;i++) { - if (mediafiles[i][0]) { - uint32_t uid = 0; - ucs2char_t mediafile[MAX_PATH]; - ucs2cpy(mediafile, mediafiles[i]); - - uid = findfile(db, mediafile, path_to_root); - if (uid <= 0) { - goto error_exit; - } - - uids = realloc(uids, sizeof(uint32_t) * (num_uids+1)); - if (!uids) { - goto error_exit; - } - uids[num_uids++] = uid; - } - } - - fp = ucs2fopen(filename, "wb"); - if (fp) { - size_t size = sizeof(uint32_t) + sizeof(uint32_t) * num_uids; - uint8_t* buffer = (uint8_t*)malloc(size); - uint8_t* p = buffer; - - if (!buffer) { - goto error_exit; - } - - p += serialize_uint32le(p, &num_uids, 1); - for (i = 0;i < (int)num_uids;++i) { - p += serialize_uint32le(p, &uids[i], 1); - } - fwrite(buffer, 1, size, fp); - free(buffer); - fclose(fp); - } else { - return -1; - } - - free(uids); - return 0; - -error_exit: - free(uids); - return -1; -} Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2007-01-18 19:44:24 UTC (rev 272) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.c 2007-01-24 10:26:45 UTC (rev 273) @@ -432,9 +432,6 @@ ip3db_set(&pmpmi->ip3db, pmpmi->records, pmpmi->num_records, NULL, 0); } - // Write out the playlist first. - ip3db_write_playlists(&pmpmi->ip3db, pmpmi->playlists, pmpmi->num_playlists, pmp->info.path_to_root); - // Write out the music database. set_filenames(dat, dic, idx, pmp); ret = ip3db_write(&pmpmi->ip3db, dat, dic, idx); Modified: trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.vcproj =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.vcproj 2007-01-18 19:44:24 UTC (rev 272) +++ trunk/pmplib/lib/pmp_iriverplus3/pmp_iriverplus3.vcproj 2007-01-24 10:26:45 UTC (rev 273) @@ -193,10 +193,6 @@ > </File> <File - RelativePath=".\plp.c" - > - </File> - <File RelativePath=".\pmp_iriverplus3.c" > </File> @@ -231,10 +227,6 @@ > </File> <File - RelativePath=".\plp.h" - > - </File> - <File RelativePath=".\serialize.h" > </File> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <suc...@us...> - 2007-02-13 21:25:33
|
Revision: 360 http://svn.sourceforge.net/pmplib/?rev=360&view=rev Author: sucknblow Date: 2007-02-13 13:25:28 -0800 (Tue, 13 Feb 2007) Log Message: ----------- Avoid implicit declaration of string.h functions Modified Paths: -------------- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c trunk/pmplib/lib/pmp_iriverplus3/util.c Modified: trunk/pmplib/lib/pmp_iriverplus3/ip3db.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2007-02-13 21:22:10 UTC (rev 359) +++ trunk/pmplib/lib/pmp_iriverplus3/ip3db.c 2007-02-13 21:25:28 UTC (rev 360) @@ -24,6 +24,9 @@ #ifdef HAVE_CONFIG_H #include <config.h> #endif/*HAVE_CONFIG_H*/ +#ifdef HAVE_STRING_H +#include <string.h> +#endif/*HAVE_STRING_H*/ #include <os.h> #include <stdio.h> Modified: trunk/pmplib/lib/pmp_iriverplus3/util.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/util.c 2007-02-13 21:22:10 UTC (rev 359) +++ trunk/pmplib/lib/pmp_iriverplus3/util.c 2007-02-13 21:25:28 UTC (rev 360) @@ -24,6 +24,9 @@ #ifdef HAVE_CONFIG_H #include <config.h> #endif/*HAVE_CONFIG_H*/ +#ifdef HAVE_STRING_H +#include <string.h> +#endif/*HAVE_STRING_H*/ #include <os.h> #include <stdio.h> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |