292 lines
5.6 KiB
C++
292 lines
5.6 KiB
C++
#include "Buffer.h"
|
|
|
|
bool Buffer::Iterator::is_start_of_line()
|
|
{
|
|
if (valid())
|
|
{
|
|
if (m_offset == 0u)
|
|
{
|
|
return true;
|
|
}
|
|
const uint8_t * a = m_buffer->address(m_offset - 1u);
|
|
a = Encoding::beginning_of_code_point(m_buffer->encoding(), a);
|
|
if (Encoding::decode(m_buffer->encoding(), a) == '\n')
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Buffer::Iterator::is_end_of_line(bool eol_only)
|
|
{
|
|
if (valid())
|
|
{
|
|
if (**this == '\n')
|
|
{
|
|
return true;
|
|
}
|
|
if (!eol_only)
|
|
{
|
|
return false;
|
|
}
|
|
Iterator i2 = *this;
|
|
if (!i2.go_forward())
|
|
{
|
|
return false;
|
|
}
|
|
if (*i2 == '\n')
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Buffer::Iterator::go_back()
|
|
{
|
|
if (valid() || (m_offset == m_buffer->size()))
|
|
{
|
|
if (m_offset == 0u)
|
|
{
|
|
m_offset = (size_t)-1;
|
|
}
|
|
else
|
|
{
|
|
const uint8_t * a = m_buffer->address(m_offset - 1u);
|
|
const uint8_t * beginning_of_code_point = Encoding::beginning_of_code_point(m_buffer->encoding(), a);
|
|
m_offset -= ((a - beginning_of_code_point) + 1u);
|
|
if (Encoding::decode(m_buffer->encoding(), address()) == '\n')
|
|
{
|
|
m_line--;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Buffer::Iterator::go_forward()
|
|
{
|
|
if (valid())
|
|
{
|
|
uint8_t size;
|
|
uint32_t c = Encoding::decode(m_buffer->encoding(), address(), &size);
|
|
m_offset += size;
|
|
if (c == '\n')
|
|
{
|
|
m_line++;
|
|
}
|
|
return true;
|
|
}
|
|
else if (m_offset == (size_t)-1)
|
|
{
|
|
m_offset = 0u;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Buffer::Iterator::go_start_of_line()
|
|
{
|
|
bool moved = false;
|
|
Iterator i2 = *this;
|
|
i2.go_back();
|
|
while (i2.valid() && (*i2 != '\n'))
|
|
{
|
|
m_offset = i2.m_offset;
|
|
moved = true;
|
|
i2.go_back();
|
|
}
|
|
return moved;
|
|
}
|
|
|
|
bool Buffer::Iterator::go_end_of_line(bool allow_eol)
|
|
{
|
|
bool moved = false;
|
|
if (go_right_in_line(allow_eol))
|
|
{
|
|
moved = true;
|
|
}
|
|
while (go_right_in_line(allow_eol))
|
|
{
|
|
;
|
|
}
|
|
return moved;
|
|
}
|
|
|
|
bool Buffer::Iterator::go_left_in_line()
|
|
{
|
|
bool moved = false;
|
|
Iterator i2 = *this;
|
|
i2.go_back();
|
|
if (i2.valid() && (*i2 != '\n'))
|
|
{
|
|
m_offset = i2.m_offset;
|
|
moved = true;
|
|
}
|
|
return moved;
|
|
}
|
|
|
|
bool Buffer::Iterator::go_right_in_line(bool allow_eol)
|
|
{
|
|
if (valid() && (**this != '\n'))
|
|
{
|
|
if (allow_eol)
|
|
{
|
|
return go_forward();
|
|
}
|
|
else
|
|
{
|
|
Iterator i2 = *this;
|
|
i2.go_forward();
|
|
if (i2.valid() && (*i2 != '\n'))
|
|
{
|
|
m_offset = i2.m_offset;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Buffer::Iterator::go_previous_line()
|
|
{
|
|
Iterator i2 = *this;
|
|
while (i2.valid())
|
|
{
|
|
i2.go_back();
|
|
if (*i2 == '\n')
|
|
{
|
|
i2.go_start_of_line();
|
|
m_line--;
|
|
m_offset = i2.m_offset;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Buffer::Iterator::go_next_line()
|
|
{
|
|
Iterator i2 = *this;
|
|
i2.go_end_of_line(true);
|
|
i2.go_forward();
|
|
if (i2.valid())
|
|
{
|
|
m_line++;
|
|
m_offset = i2.m_offset;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void Buffer::Iterator::warp_to_offset(size_t offset)
|
|
{
|
|
Iterator i = m_buffer->begin();
|
|
m_offset = i.m_offset;
|
|
m_line = i.m_line;
|
|
for (;;)
|
|
{
|
|
i.go_forward();
|
|
if (i.m_offset > offset)
|
|
{
|
|
break;
|
|
}
|
|
m_offset = i.m_offset;
|
|
m_line = i.m_line;
|
|
if (!i.valid())
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool Buffer::Iterator::go_forward_in_line_up_to_char(uint32_t c)
|
|
{
|
|
size_t last_offset = m_offset;
|
|
Buffer::Iterator it = *this;
|
|
while (it.go_right_in_line(false))
|
|
{
|
|
if (*it == c)
|
|
{
|
|
if (last_offset != m_offset)
|
|
{
|
|
m_offset = last_offset;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
last_offset = it.m_offset;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Buffer::Iterator::go_forward_in_line_on_to_char(uint32_t c)
|
|
{
|
|
Buffer::Iterator it = *this;
|
|
while (it.go_right_in_line(false))
|
|
{
|
|
if (*it == c)
|
|
{
|
|
m_offset = it.m_offset;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Buffer::Iterator::go_backward_in_line_up_to_char(uint32_t c)
|
|
{
|
|
size_t last_offset = m_offset;
|
|
Buffer::Iterator it = *this;
|
|
while (it.go_left_in_line())
|
|
{
|
|
if (*it == c)
|
|
{
|
|
if (last_offset != m_offset)
|
|
{
|
|
m_offset = last_offset;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
last_offset = it.m_offset;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Buffer::Iterator::go_backward_in_line_on_to_char(uint32_t c)
|
|
{
|
|
Buffer::Iterator it = *this;
|
|
while (it.go_left_in_line())
|
|
{
|
|
if (*it == c)
|
|
{
|
|
m_offset = it.m_offset;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
Buffer::Iterator Buffer::Iterator::prev()
|
|
{
|
|
Iterator i = *this;
|
|
i.go_back();
|
|
return i;
|
|
}
|
|
|
|
Buffer::Iterator Buffer::Iterator::next()
|
|
{
|
|
Iterator i = *this;
|
|
i.go_forward();
|
|
return i;
|
|
}
|