diff options
Diffstat (limited to 'src/piece-table.c')
-rw-r--r-- | src/piece-table.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/src/piece-table.c b/src/piece-table.c index 490950b..be9f1b2 100644 --- a/src/piece-table.c +++ b/src/piece-table.c @@ -1,3 +1,4 @@ +#include <assert.h> #include "piece-table.h" static piece *make_piece() { @@ -39,6 +40,16 @@ bool init_piece_table(piece_table *pt, char *orig) { return true; } + +static void free_piece_list(piece *p) { + piece *cur, *next; + assert(p != NULL); + for ( cur = p; cur != p; cur = next ) { + next = cur->next; + free( cur ); + } +} + void free_piece_table(piece_table *pt) { free_growable_buffer(&pt->add); free_fixed_buffer(&pt->orig); @@ -49,6 +60,48 @@ void free_piece_table(piece_table *pt) { pt->length = 0; } -void free_piece_list(piece *pt) { + +static void find_piece_by_pos(piece_table *pt, size_t pos) { + piece *cur; + assert(pos < pt->length); + if ( pos >= pt->cached_offset ) { + /* Search forward */ + for ( cur = pt->cached; ; cur = cur->next ) { + if ( pt->cached_offset + pt->length > pos ) { + pt->cached = cur; + assert(pt->cached != pt->sentinel); + return; + } + pt->cached_offset += cur->length; + } + } else { + /* Search backwards */ + for ( cur = pt->cached->prev; ; cur = cur->prev ) { + pt->cached_offset -= cur->length; + if ( pt->cached_offset < pos ) { + pt->cached = cur; + assert(pt->cached != pt->sentinel); + return; + } + } + } +} + +char index_piece_table(piece_table *pt, size_t pos) { + assert(pos < pt->length); + find_piece_by_pos(pt, pos); + return pt->cached->start[pos - pt->cached_offset]; +} + +void insert_piece_table(piece_table *pt, char val, size_t pos) { + /* At the moment inserts only one char */ + append_growable_buffer(&pt->add, &val, 1); + + find_piece_by_pos(pt, pos); + // TODO } + +void delete_piece_table(piece_table *pt, size_t pos, size_t len) { + +} |