72 lines
1.5 KiB
C++
72 lines
1.5 KiB
C++
#include "vase/append_buffer.h"
|
|
|
|
AppendBuffer::AppendBuffer() {
|
|
new_text_chunk();
|
|
new_line_chunk();
|
|
}
|
|
|
|
AppendBuffer::~AppendBuffer() {
|
|
for (auto p : buf)
|
|
free(p);
|
|
for (auto p : newlines)
|
|
free(p);
|
|
}
|
|
|
|
inline void AppendBuffer::key(char c) {
|
|
if (t_offset == CHUNK_SIZE)
|
|
new_text_chunk();
|
|
(*t_current)[t_offset++] = c;
|
|
if (c == '\n') {
|
|
if (l_offset == CHUNK_SIZE)
|
|
new_line_chunk();
|
|
(*l_current)[l_offset++] = current_offset;
|
|
}
|
|
++current_offset;
|
|
}
|
|
|
|
void AppendBuffer::append(const char *text, uint32_t length) {
|
|
while (length) {
|
|
uint32_t space = CHUNK_SIZE - t_offset;
|
|
if (space == 0) {
|
|
new_text_chunk();
|
|
space = CHUNK_SIZE;
|
|
}
|
|
uint32_t copy = length < space ? length : space;
|
|
_append(text, copy);
|
|
text += copy;
|
|
length -= copy;
|
|
}
|
|
}
|
|
|
|
inline void AppendBuffer::new_text_chunk() {
|
|
t_current = (TChunk *)malloc(sizeof(TChunk));
|
|
buf.push_back(t_current);
|
|
t_offset = 0;
|
|
}
|
|
|
|
inline void AppendBuffer::new_line_chunk() {
|
|
l_current = (LChunk *)malloc(sizeof(LChunk));
|
|
newlines.push_back(l_current);
|
|
l_offset = 0;
|
|
}
|
|
|
|
inline void AppendBuffer::_append(const char *text, uint32_t length) {
|
|
memcpy((*t_current) + t_offset, text, length);
|
|
|
|
const char *p = text;
|
|
const char *end = text + length;
|
|
|
|
while (p < end) {
|
|
p = (const char *)memchr(p, '\n', end - p);
|
|
if (!p)
|
|
break;
|
|
if (l_offset == CHUNK_SIZE)
|
|
new_line_chunk();
|
|
(*l_current)[l_offset++] = current_offset + uint32_t(p - text);
|
|
p++;
|
|
}
|
|
|
|
t_offset += length;
|
|
current_offset += length;
|
|
}
|