#ifndef GAPBUFFER_H #define GAPBUFFER_H #include #include #include "Encoding.h" #include #include class GapBuffer { public: class Iterator { public: Iterator(GapBuffer * gap_buffer) { m_gap_buffer = gap_buffer; m_offset = 0u; } bool valid() const { return m_offset < m_gap_buffer->size(); } void forward(); bool check_forward(); void back(); bool check_back(); uint8_t * address() const { return m_gap_buffer->address(m_offset); } uint32_t operator*() const { if (valid()) { return Encoding::decode(m_gap_buffer->m_encoding, address()); } else { return 0xFFFFFFFFu; } } GapBuffer * gap_buffer() { return m_gap_buffer; } bool operator<(const Iterator & other) { return m_offset < other.m_offset; } protected: GapBuffer * m_gap_buffer; size_t m_offset; }; class Cursor { public: Cursor(GapBuffer * gap_buffer) : m_iterator(gap_buffer) { m_line = 0u; init_column(); } bool is_start_of_line(); bool is_end_of_line() { return *m_iterator == '\n'; } bool go_start_of_line(); bool go_end_of_line(); bool go_left(); bool go_right(); bool operator<(const Cursor & other) { return m_iterator < other.m_iterator; } protected: Iterator m_iterator; size_t m_line; size_t m_column; void init_column(); void calculate_column(); }; uint8_t tabstop; GapBuffer(Encoding::Type encoding); GapBuffer(uint8_t * buffer, size_t buffer_size, size_t size, Encoding::Type encoding); ~GapBuffer(); size_t buffer_size() const { return m_buffer_size; } size_t size() const { return m_size; } std::shared_ptr add_cursor(); uint8_t * address(size_t offset) const { if (offset < m_gap_position) { return &m_buffer[offset]; } else { return &m_buffer[offset + (m_buffer_size - m_size)]; } } protected: uint8_t * m_buffer; size_t m_buffer_size; size_t m_size; size_t m_gap_position; Encoding::Type m_encoding; std::list> m_cursors; }; #endif