#ifndef PIECETABLE_H #define PIECETABLE_H #include #include "PagedBuffer.h" #include #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 m_append_buffer; PagedBuffer m_piece_descriptors; PagedBuffer m_change_descriptors; }; #endif