From 87a4a813bc1700d388105bdc01ba2c61c2f8f309 Mon Sep 17 00:00:00 2001 From: Petr Tesarik Date: Tue, 9 Oct 2012 14:30:08 +0200 Subject: [PATCH] Fix insert beyond EOF It turns out that split_block() can be called on the EOF block, so I cannot split off the tail, but instead have to re-create the head. --- libhed/file.c | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/libhed/file.c b/libhed/file.c index c113b90..971d0d3 100644 --- a/libhed/file.c +++ b/libhed/file.c @@ -551,34 +551,36 @@ file_kill_block(struct hed_file *file, struct file_block *block) file_kill_block(file, prev); } -static struct file_block * +static struct hed_block * split_block(struct hed_file *file, struct hed_block *block, hed_uoff_t splitpoint) { - struct file_block *next; + struct hed_block *head; - next = new_block(file, block->flags); - if (!next) + head = new_block(file, block->flags & ~HED_BLOCK_EOF); + if (!head) return NULL; - if ( (next->dataobj = block->dataobj) ) { - cache_get(next->dataobj); - next->dataoff = block->dataoff + splitpoint; + if ( (head->dataobj = block->dataobj) ) { + cache_get(head->dataobj); + head->dataoff = block->dataoff; + block->dataoff += splitpoint; } else assert(hed_block_is_virtual(block)); - next->t.size = block->t.size - splitpoint; - next->phys_pos = block->phys_pos; - if (!hed_block_is_inserted(block)) - next->phys_pos += splitpoint; + head->t.size = splitpoint; + head->phys_pos = block->phys_pos; - block->t.size = splitpoint; + block->t.size -= splitpoint; + if (!hed_block_is_inserted(block)) + block->phys_pos += splitpoint; recalc_block_recursive(block); - recalc_chain_block_before(file_blocks(file), next, next_block(block)); + recalc_chain_block_before(hed_file_blocks(file), head, block); - move_cursors(block, next, splitpoint, UOFF_MAX, -splitpoint); + move_cursors(block, head, 0, splitpoint - 1, 0); + move_cursors(block, block, splitpoint, UOFF_MAX, -splitpoint); - return next; + return head; } /* Replace a chunk in @block with @newblock */ @@ -1631,9 +1633,11 @@ file_erase_continuous(struct hed_file *file, blockoff_t *blockoff, size_t len) block->dataoff += len; if (!hed_block_is_inserted(block)) block->phys_pos += len; - } else if (block_offset + len < block->t.size && - !split_block(file, block, block_offset + len)) - return -1; + } else if (block_offset + len < block->t.size) { + block = split_block(file, block, block_offset + len); + if (!block) + return -1; + } move_cursors(block, block, block_offset, UOFF_MAX, -(hed_uoff_t)len); @@ -1686,7 +1690,7 @@ int hed_file_insert_begin(struct hed_file *file, const hed_cursor_t *curs, hed_cursor_t *curs_ins) { - struct file_block *block, *newblock; + struct file_block *newblock; BDEBUG("Starting insert at %llx\n", curs->pos); @@ -1702,16 +1706,12 @@ hed_file_insert_begin(struct hed_file *file, const hed_cursor_t *curs, return -1; } - block = curs->block; - if (curs->off) { - block = split_block(file, block, curs->off); - if (!block) { - file_free_block(file, newblock); - return -1; - } + if (curs->off && !split_block(file, curs->block, curs->off)) { + file_free_block(file, newblock); + return -1; } - chain_block_before(file_blocks(file), newblock, block); + chain_block_before(file_blocks(file), newblock, curs->block); curs_ins->pos = curs->pos; curs_ins->off = newblock->t.size; -- 2.11.4.GIT