jes/src/core/PieceTable.h

98 lines
2.5 KiB
C++

#ifndef PIECETABLE_H
#define PIECETABLE_H
#include <stdint.h>
#include "PagedBuffer.h"
#include <utility>
#define PIECE_DESCRIPTOR_INDEX_START 0u
#define PIECE_DESCRIPTOR_INDEX_END 1u
#define PIECE_DESCRIPTOR_N_CHARS_EOL_FLAG_MASK 0x80000000u
class PieceTable
{
public:
struct PieceDescriptor
{
/** The previous piece descriptor in the chain. */
PieceDescriptor * prev;
/** The next piece descriptor in the chain. */
PieceDescriptor * next;
/** Text that the piece describes. */
uint8_t * start;
/** Length of the text (in bytes). */
uint32_t length;
/**
* Number of characters in the text.
* Also, the highest bit is the eol flag.
*/
uint32_t n_chars;
/** Get the number of characters pointed to by this descriptor. */
uint32_t get_n_chars() { return n_chars & (~PIECE_DESCRIPTOR_N_CHARS_EOL_FLAG_MASK); }
/** Get whether this descriptor is the end of a line. */
bool eol() { return (n_chars & PIECE_DESCRIPTOR_N_CHARS_EOL_FLAG_MASK) != 0u; }
/** Toggle whether this descriptor is the end of a line. */
void toggle_eol() { n_chars ^= PIECE_DESCRIPTOR_N_CHARS_EOL_FLAG_MASK; }
};
struct Position
{
/** The piece. */
PieceDescriptor * pd;
/** Byte offset within the piece. */
uint32_t offset;
};
struct ChangeDescriptor
{
uint32_t piece_descriptor_index;
uint32_t from_val;
uint32_t to_val;
uint8_t attr_idx;
};
PieceTable(const uint8_t * file_buffer, unsigned long file_buffer_size);
PieceDescriptor * add_piece_descriptor()
{
return &m_piece_descriptors[m_piece_descriptor_index++];
}
PieceDescriptor & operator[](uint32_t index)
{
return m_piece_descriptors[index];
}
uint32_t get_num_lines() { return m_num_lines; }
PieceDescriptor * start_descriptor;
PieceDescriptor * end_descriptor;
Position cursor_position;
void append_initial_line_piece(uint8_t * start, uint32_t length, uint32_t n_chars, bool eol);
protected:
const uint8_t * m_file_buffer;
unsigned long m_file_buffer_size;
uint32_t m_num_lines;
/** Next available piece descriptor index. */
uint32_t m_piece_descriptor_index;
PagedBuffer<uint8_t> m_append_buffer;
PagedBuffer<PieceDescriptor> m_piece_descriptors;
PagedBuffer<ChangeDescriptor> m_change_descriptors;
};
#endif