jes/src-c/core/Buffer-Iterator.cc
2018-07-25 20:47:02 -04:00

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