diff --git a/src/core/Buffer.cc b/src/core/Buffer.cc index c5225fd..80fe4b4 100644 --- a/src/core/Buffer.cc +++ b/src/core/Buffer.cc @@ -56,16 +56,14 @@ bool Buffer::load_from_file(const char * filename) m_piece_table = std::make_shared(m_file_buffer, m_file_buffer_size); for (auto it = text_loader.begin(); it != text_loader.end(); it++) { - auto pd_n = m_piece_table->add_piece_descriptor(); - PieceTable::PieceDescriptor & pd = pd_n.second; - pd.prev = m_piece_table->end_descriptor->prev; - pd.next = PIECE_DESCRIPTOR_INDEX_END; - pd.start = it->first - m_file_buffer; - pd.length = it->second; - pd.n_chars = it->second; /* TODO: fix this for other encodings */ - pd.eol = 1u; - (*m_piece_table)[m_piece_table->end_descriptor->prev].next = pd_n.first; - m_piece_table->end_descriptor->prev = pd_n.first; + PieceTable::PieceDescriptor * pd = m_piece_table->add_piece_descriptor(); + pd->prev = m_piece_table->end_descriptor->prev; + pd->next = m_piece_table->end_descriptor; + pd->start = it->first; + pd->length = it->second; + pd->n_chars = it->second | PIECE_DESCRIPTOR_N_CHARS_EOL_FLAG_MASK; /* TODO: fix this for other encodings */ + m_piece_table->end_descriptor->prev->next = pd; + m_piece_table->end_descriptor->prev = pd; } return true; diff --git a/src/core/PieceTable.cc b/src/core/PieceTable.cc index 440109b..1e65596 100644 --- a/src/core/PieceTable.cc +++ b/src/core/PieceTable.cc @@ -6,7 +6,7 @@ PieceTable::PieceTable(const uint8_t * file_buffer, unsigned long file_buffer_si m_file_buffer_size = file_buffer_size; start_descriptor = &m_piece_descriptors[PIECE_DESCRIPTOR_INDEX_START]; end_descriptor = &m_piece_descriptors[PIECE_DESCRIPTOR_INDEX_END]; - start_descriptor->next = PIECE_DESCRIPTOR_INDEX_END; - end_descriptor->prev = PIECE_DESCRIPTOR_INDEX_START; + start_descriptor->next = end_descriptor; + end_descriptor->prev = start_descriptor; m_piece_descriptor_index = 2u; } diff --git a/src/core/PieceTable.h b/src/core/PieceTable.h index e2a0da0..c8cc5fc 100644 --- a/src/core/PieceTable.h +++ b/src/core/PieceTable.h @@ -8,17 +8,39 @@ #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 { - uint32_t prev; - uint32_t next; - uint32_t start; + /** 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; - uint32_t eol; + + /** 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 ChangeDescriptor @@ -31,12 +53,9 @@ public: PieceTable(const uint8_t * file_buffer, unsigned long file_buffer_size); - std::pair add_piece_descriptor() + PieceDescriptor * add_piece_descriptor() { - uint32_t index = m_piece_descriptor_index; - m_piece_descriptor_index++; - PieceDescriptor & pd = m_piece_descriptors[index]; - return std::pair(index, pd); + return &m_piece_descriptors[m_piece_descriptor_index++]; } PieceDescriptor & operator[](uint32_t index)