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