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