From fca838fcbfeac1111ff715230075f8c608f3c84c Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Mon, 9 Jan 2017 22:11:08 -0500 Subject: [PATCH] fix problem of record_change() not receiving contiguous range by using GapBuffer::copy_to() --- src/core/Buffer.cc | 37 ++++++++++++++++++------------------- src/core/Buffer.h | 2 +- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/core/Buffer.cc b/src/core/Buffer.cc index 6a36d43..ddc9021 100644 --- a/src/core/Buffer.cc +++ b/src/core/Buffer.cc @@ -184,7 +184,7 @@ void Buffer::insert_code_point(const Buffer::Iterator & position, uint32_t code_ void Buffer::insert_data(size_t offset, const uint8_t data[], size_t length) { m_gap_buffer->insert(offset, data, length); - record_change(data, length, offset, true); + record_change(offset, length, true); warp_iterators_after_insert(offset, length); post_warp_cursors(); } @@ -202,8 +202,7 @@ void Buffer::erase_code_point(const Buffer::Iterator & position) void Buffer::erase_data(size_t offset, size_t length) { warp_iterators_before_delete(offset, length); - /* FIXME: erased data may not be contiguous in gap buffer. */ - record_change(m_gap_buffer->address(offset), length, offset, false); + record_change(offset, length, false); m_gap_buffer->erase(offset, length); post_warp_cursors(); } @@ -281,7 +280,7 @@ void Buffer::pop_operation() } } -void Buffer::record_change(const uint8_t data[], size_t length, size_t buffer_position, bool insert) +void Buffer::record_change(size_t offset, size_t length, bool insert) { if (!m_current_change_operation) { @@ -294,41 +293,41 @@ void Buffer::record_change(const uint8_t data[], size_t length, size_t buffer_po * modified to encompass the new change. */ ChangeUnit & cu = *m_current_change_operation->changes.rbegin(); if (insert && cu.insert && - ((buffer_position + length) >= cu.buffer_position) && - (buffer_position <= (cu.buffer_position + cu.length))) + ((offset + length) >= cu.buffer_position) && + (offset <= (cu.buffer_position + cu.length))) { /* The new insertion can extend the previous insertion change unit. */ - size_t change_buffer_offset = cu.change_buffer_offset + buffer_position - cu.buffer_position; - m_change_buffer->insert(change_buffer_offset, data, length); + size_t change_buffer_offset = cu.change_buffer_offset + offset - cu.buffer_position; + m_gap_buffer->copy_to(offset, length, *m_change_buffer, change_buffer_offset); cu.length += length; cu.change_buffer_offset = std::min(cu.change_buffer_offset, change_buffer_offset); - cu.buffer_position = std::min(cu.buffer_position, buffer_position); + cu.buffer_position = std::min(cu.buffer_position, offset); return; } else if ((!insert) && (!cu.insert) && - ((buffer_position == cu.buffer_position) || - ((buffer_position + length) == cu.buffer_position))) + ((offset == cu.buffer_position) || + ((offset + length) == cu.buffer_position))) { /* The new deletion can extend the previous deletion change unit. */ - if (buffer_position == cu.buffer_position) + if (offset == cu.buffer_position) { /* The new deletion immediately follows the previous. */ - m_change_buffer->insert(cu.change_buffer_offset + cu.length, data, length); + m_gap_buffer->copy_to(offset, length, *m_change_buffer, cu.change_buffer_offset + cu.length); } else { /* The new deletion immediately precedes the previous. */ - m_change_buffer->insert(cu.change_buffer_offset, data, length); + m_gap_buffer->copy_to(offset, length, *m_change_buffer, cu.change_buffer_offset); } cu.length += length; return; } else if ((!insert) && cu.insert && - (buffer_position >= cu.buffer_position) && - ((buffer_position + length) <= (cu.buffer_position + cu.length))) + (offset >= cu.buffer_position) && + ((offset + length) <= (cu.buffer_position + cu.length))) { /* The deletion is removing from the previous insertion change unit. */ - m_change_buffer->erase(cu.change_buffer_offset + (buffer_position - cu.buffer_position), length); + m_change_buffer->erase(cu.change_buffer_offset + (offset - cu.buffer_position), length); if (cu.length <= length) { m_current_change_operation->changes.erase(--m_current_change_operation->changes.end()); @@ -342,11 +341,11 @@ void Buffer::record_change(const uint8_t data[], size_t length, size_t buffer_po } /* Start a new change unit. */ size_t change_buffer_offset = m_change_buffer->size(); - m_change_buffer->insert(change_buffer_offset, data, length); + m_gap_buffer->copy_to(offset, length, *m_change_buffer, change_buffer_offset); ChangeUnit cu; cu.change_buffer_offset = change_buffer_offset; cu.length = length; - cu.buffer_position = buffer_position; + cu.buffer_position = offset; cu.insert = insert; m_current_change_operation->changes.push_back(cu); } diff --git a/src/core/Buffer.h b/src/core/Buffer.h index 26b68c3..b234796 100644 --- a/src/core/Buffer.h +++ b/src/core/Buffer.h @@ -157,7 +157,7 @@ protected: void load_empty_buffer(); bool load_from_memory(const uint8_t * data, size_t data_length); void load_text_in_buffer(uint8_t * buffer, size_t buffer_size, size_t data_length); - void record_change(const uint8_t data[], size_t length, size_t buffer_position, bool insert); + void record_change(size_t offset, size_t length, bool insert); void save_current_operation(); void warp_iterators_after_insert(size_t offset, size_t length); void warp_iterators_before_delete(size_t offset, size_t length);