fix problem of record_change() not receiving contiguous range by using GapBuffer::copy_to()

This commit is contained in:
Josh Holtrop 2017-01-09 22:11:08 -05:00
parent b9313ad606
commit fca838fcbf
2 changed files with 19 additions and 20 deletions

View File

@ -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);
}

View File

@ -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);