refactor Buffer insert and delete operations

add Buffer functions to insert/erase data chunks
This commit is contained in:
Josh Holtrop 2017-01-09 21:34:16 -05:00
parent 66aa9c5235
commit f3753be4eb
2 changed files with 79 additions and 28 deletions

View File

@ -171,49 +171,61 @@ void Buffer::exit_insert_mode()
void Buffer::insert_code_point(const Buffer::Iterator & position, uint32_t code_point)
{
push_operation();
Buffer::Iterator local_position = position;
if ((code_point != '\n') && (size() == 0u))
{
insert_code_point(position, '\n');
}
uint8_t encoded[Encoding::MAX_CODE_POINT_SIZE];
uint8_t encoded[Encoding::MAX_CODE_POINT_SIZE * 2];
uint8_t bytes = Encoding::encode(code_point, m_encoding, encoded);
m_gap_buffer->insert(local_position.offset(), encoded, bytes);
record_change(encoded, bytes, local_position.offset(), true);
ssize_t lines = (code_point == '\n') ? 1 : 0;
warp_iterators(local_position.offset(), bytes, lines, true);
if ((size() == 0u) && (code_point != '\n'))
{
bytes += Encoding::encode('\n', m_encoding, &encoded[bytes]);
}
insert_data(position.offset(), encoded, bytes);
pop_operation();
}
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);
warp_iterators_after_insert(offset, length);
post_warp_cursors();
}
void Buffer::erase_code_point(const Buffer::Iterator & position)
{
if (position.valid())
{
push_operation();
Buffer::Iterator local_position = position;
uint8_t bytes = 0u;
uint32_t code_point = Encoding::decode(m_encoding, local_position.address(), &bytes);
record_change(local_position.address(), bytes, local_position.offset(), false);
m_gap_buffer->erase(local_position.offset(), bytes);
ssize_t lines = (code_point == '\n') ? -1 : 0;
warp_iterators(local_position.offset(), -(ssize_t)bytes, lines, false);
erase_data(position.offset(), Encoding::num_bytes_in_code_point(m_encoding, position.address()));
pop_operation();
}
}
void Buffer::warp_iterators(size_t offset, ssize_t offset_adjustment, ssize_t lines_adjustment, bool include_equal)
void Buffer::erase_data(size_t offset, size_t length)
{
if (!include_equal)
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);
m_gap_buffer->erase(offset, length);
post_warp_cursors();
}
size_t Buffer::lines_in_data(size_t offset, size_t length)
{
size_t lines = 0u;
for (size_t i = 0u; i < length; )
{
offset++;
}
for (auto iterator : m_iterators)
{
if (iterator->offset() >= offset)
uint8_t bytes;
uint32_t c = Encoding::decode(m_encoding, m_gap_buffer->address(offset), &bytes);
if (c == '\n')
{
iterator->warp(offset_adjustment, lines_adjustment);
lines++;
}
i += bytes;
}
return lines;
}
void Buffer::post_warp_cursors()
{
for (auto cursor : m_cursors)
{
if ((*cursor == *m_eof_iterator) && (size() > 0u))
@ -223,6 +235,40 @@ void Buffer::warp_iterators(size_t offset, ssize_t offset_adjustment, ssize_t li
}
}
void Buffer::warp_iterators_after_insert(size_t offset, size_t length)
{
size_t lines = lines_in_data(offset, length);
for (auto iterator : m_iterators)
{
if (iterator->offset() >= offset)
{
iterator->warp(length, lines);
}
}
}
void Buffer::warp_iterators_before_delete(size_t offset, size_t length)
{
size_t lines = lines_in_data(offset, length);
for (auto iterator : m_iterators)
{
/* Move any iterators within the chunk to be deleted to after it. */
while ((iterator->offset() >= offset) &&
(iterator->offset() < (offset + length)))
{
iterator->go_forward();
if (!iterator->valid())
{
break;
}
}
if (iterator->offset() >= offset)
{
iterator->warp(-(ssize_t)length, -(ssize_t)lines);
}
}
}
void Buffer::pop_operation()
{
if (m_operation_level > 0)
@ -235,7 +281,7 @@ void Buffer::pop_operation()
}
}
void Buffer::record_change(uint8_t data[], size_t length, size_t buffer_position, bool insert)
void Buffer::record_change(const uint8_t data[], size_t length, size_t buffer_position, bool insert)
{
if (!m_current_change_operation)
{

View File

@ -152,9 +152,14 @@ 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(uint8_t data[], size_t length, size_t buffer_position, bool insert);
void record_change(const uint8_t data[], size_t length, size_t buffer_position, bool insert);
void save_current_operation();
void warp_iterators(size_t offset, ssize_t offset_adjustment, ssize_t lines_adjustments, bool include_equal);
void warp_iterators_after_insert(size_t offset, size_t length);
void warp_iterators_before_delete(size_t offset, size_t length);
void insert_data(size_t offset, const uint8_t data[], size_t length);
void erase_data(size_t offset, size_t length);
size_t lines_in_data(size_t offset, size_t length);
void post_warp_cursors();
};
#endif