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