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. |