95 lines
2.2 KiB
C++
95 lines
2.2 KiB
C++
#ifndef CURSOR_H
|
|
#define CURSOR_H
|
|
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include "Encoding.h"
|
|
#include "GapBuffer.h"
|
|
|
|
class Iterator
|
|
{
|
|
public:
|
|
Iterator(GapBuffer * gap_buffer, Encoding::Type encoding)
|
|
{
|
|
m_gap_buffer = gap_buffer;
|
|
m_offset = 0u;
|
|
m_encoding = encoding;
|
|
}
|
|
bool valid() const
|
|
{
|
|
return m_offset < m_gap_buffer->size();
|
|
}
|
|
void go_forward();
|
|
bool check_go_forward();
|
|
void go_back();
|
|
bool check_go_back();
|
|
uint8_t * address() const
|
|
{
|
|
return m_gap_buffer->address(m_offset);
|
|
}
|
|
uint32_t operator*() const
|
|
{
|
|
if (valid())
|
|
{
|
|
return Encoding::decode(m_encoding, address());
|
|
}
|
|
else
|
|
{
|
|
return 0xFFFFFFFFu;
|
|
}
|
|
}
|
|
GapBuffer * gap_buffer() const { return m_gap_buffer; }
|
|
bool operator<(const Iterator & other) const
|
|
{
|
|
return m_offset < other.m_offset;
|
|
}
|
|
size_t offset() { return m_offset; }
|
|
void set_offset(size_t new_offset) { m_offset = new_offset; }
|
|
|
|
protected:
|
|
GapBuffer * m_gap_buffer;
|
|
size_t m_offset;
|
|
Encoding::Type m_encoding;
|
|
};
|
|
|
|
class Cursor
|
|
{
|
|
public:
|
|
Cursor(GapBuffer * gap_buffer, Encoding::Type encoding)
|
|
: m_iterator(gap_buffer, encoding)
|
|
{
|
|
m_line = 0u;
|
|
init_column();
|
|
}
|
|
bool is_start_of_line();
|
|
bool is_end_of_line(bool allow_eol);
|
|
bool go_start_of_line();
|
|
bool go_end_of_line(bool allow_eol);
|
|
bool go_left();
|
|
bool go_right(bool allow_eol);
|
|
bool go_up(size_t target_column);
|
|
bool go_down(size_t target_column);
|
|
bool operator<(const Cursor & other) const
|
|
{
|
|
return m_iterator < other.m_iterator;
|
|
}
|
|
uint32_t operator*() const { return *m_iterator; }
|
|
uint8_t * address() const { return m_iterator.address(); }
|
|
bool valid() const { return m_iterator.valid(); }
|
|
size_t line() const { return m_line; }
|
|
size_t column() const { return m_column; }
|
|
Iterator & iterator() { return m_iterator; }
|
|
void set_line(size_t line) { m_line = line; }
|
|
void calculate_column();
|
|
|
|
protected:
|
|
Iterator m_iterator;
|
|
size_t m_line;
|
|
size_t m_column;
|
|
|
|
void init_column();
|
|
void forward_to_column(size_t target_column);
|
|
};
|
|
|
|
#endif
|