From: <ny...@us...> - 2007-01-26 15:39:13
|
Revision: 287 http://svn.sourceforge.net/pmplib/?rev=287&view=rev Author: nyaochi Date: 2007-01-26 07:39:06 -0800 (Fri, 26 Jan 2007) Log Message: ----------- Prevent a possible problem in byte-order conversion. I found a node converted twice since it was referred by multiple indices in a database updated by the player. Modified Paths: -------------- trunk/pmplib/frontend/easypmp/cui/option.c trunk/pmplib/lib/pmp_iriverplus3/idx.c Modified: trunk/pmplib/frontend/easypmp/cui/option.c =================================================================== --- trunk/pmplib/frontend/easypmp/cui/option.c 2007-01-26 13:27:21 UTC (rev 286) +++ trunk/pmplib/frontend/easypmp/cui/option.c 2007-01-26 15:39:06 UTC (rev 287) @@ -155,7 +155,7 @@ int this_option_optind = optind ? optind : 1; int option_index = 0; static const struct option long_options[] = { - {"create", no_argument, 0, 'c'}, + {"create", no_argument, 0, 'c'}, {"update", no_argument, 0, 'u'}, {"source", required_argument, 0, 'z'}, {"repr", no_argument, 0, 'R'}, Modified: trunk/pmplib/lib/pmp_iriverplus3/idx.c =================================================================== --- trunk/pmplib/lib/pmp_iriverplus3/idx.c 2007-01-26 13:27:21 UTC (rev 286) +++ trunk/pmplib/lib/pmp_iriverplus3/idx.c 2007-01-26 15:39:06 UTC (rev 287) @@ -84,6 +84,7 @@ uint8_t* buffer; uint32_t size; uint32_t offset; + uint8_t* be_flag; }; typedef int (*avl_comp_t)(avl_t* avl, uint32_t x, uint32_t y); @@ -96,6 +97,7 @@ static void avl_finish(avl_t* avl) { free(avl->buffer); + free(avl->be_flag); free(avl); } @@ -148,7 +150,12 @@ static void avl_rewind(avl_t* avl, uint32_t offset) { memset(avlnode(avl, offset), 0, avl->offset - offset); - avl->offset = offset; + //if (avl->offset / PAGESIZE == offset / PAGESIZE) { + avl->offset = offset; + /*} else { + uint32_t page = avl->offset / PAGESIZE; + avl->offset = PAGESIZE * page + sizeof(header_t); + }*/ } static uint32_t avlnode_new(avl_t* avl, size_t keysize) @@ -493,6 +500,14 @@ int field = dic_table->indices[index].fields[level]; int type = dic_table->fields[field].type; + /* Skip this node if already converted to the native byte-order. */ + if (avl->be_flag[offset]) { + return; + } + + /* This node is converted to the native byte-order. */ + avl->be_flag[offset] = 1; + /* Convert the current node. */ from_uint32be(&node->left); from_uint32be(&node->right); @@ -526,14 +541,16 @@ from_be_avltree(avl, node->tail, dic_table, index, level+1); } else { /* Convert the tail. */ - avltail_t* tail = (avltail_t*)avlnode(avl, node->tail); - for (;;) { + uint32_t tail_offset = node->tail; + while (!avl->be_flag[tail_offset]) { + avltail_t* tail = (avltail_t*)avlnode(avl, tail_offset); from_uint32be(&tail->next); from_uint32be(&tail->data); + avl->be_flag[tail_offset] = 1; /* Mark this tail. */ if (!tail->next) { break; } - tail = (avltail_t*)avlnode(avl, tail->next); + tail_offset = tail->next; } } } @@ -731,6 +748,14 @@ offset += PAGESIZE; } + /* + * Allocate memory block for indicating the status of byte-order conversion. + * This is really ugly, but we had to prevent a node from being converted twice. + * At first, I didn't think this treatment is necessary, but I found a node + * referred by multiple indices in a database generated by my E10 player. + */ + idx->avl->be_flag = calloc(idx->avl->size, 1); + /* 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); @@ -750,6 +775,10 @@ from_be_avltree(idx->avl, idx_root, &dic->objects, i, 0); } } + + /* Free the memory block for big-endian flags. */ + free(idx->avl->be_flag); + idx->avl->be_flag = NULL; return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |