Finish basic buffer implementation.

This commit is contained in:
Kyle Isom 2023-10-09 12:45:19 -07:00
parent 1bc5bc0b10
commit f8041c2bfa
3 changed files with 92 additions and 14 deletions

View File

@ -29,7 +29,7 @@ nearestPower(size_t x)
x |= x >> 16;
x |= x >> 32;
return x;
return x+1;
}
@ -56,6 +56,14 @@ Buffer::Buffer(const char *data)
}
bool
Buffer::Append(const char *s)
{
size_t slen = strnlen(s, maxReasonableLine);
return this->Append((uint8_t *)s, slen);
}
bool
Buffer::Append(uint8_t *data, size_t datalen)
{
@ -78,12 +86,23 @@ Buffer::Append(uint8_t c)
return this->Append(&c, 1);
}
bool
Buffer::Insert(size_t index, const char *s)
{
size_t slen = strnlen(s, maxReasonableLine);
return this->Insert(index, (uint8_t *)(s), slen);
}
bool
Buffer::Insert(size_t index, uint8_t *data, size_t datalen)
{
auto resized = this->shift(index, datalen);
auto resized = this->shiftRight(index, datalen);
memcpy(this->contents + index, data, datalen);
this->length += datalen;
return resized;
}
@ -94,6 +113,23 @@ Buffer::Insert(size_t index, uint8_t c)
}
bool
Buffer::Remove(size_t index, size_t count)
{
auto resized = this->shiftLeft(index, count);
this->length -= count;
return resized;
}
bool
Buffer::Remove(size_t index)
{
return this->Remove(index, 1);
}
void
Buffer::Resize(size_t newCapacity)
{
@ -103,6 +139,7 @@ Buffer::Resize(size_t newCapacity)
uint8_t *newContents = new uint8_t[newCapacity];
memset(newContents, 0, newCapacity);
if (this->length > 0) {
memcpy(newContents, this->contents, this->length);
}
@ -140,8 +177,9 @@ Buffer::Clear()
void
Buffer::Reclaim()
{
this->Clear();
delete this->contents;
this->length = 0;
this->capacity = 0;
}
@ -158,7 +196,7 @@ Buffer::mustGrow(size_t delta)
bool
Buffer::shift(size_t offset, size_t delta)
Buffer::shiftRight(size_t offset, size_t delta)
{
auto resized = false;
auto newCap = this->mustGrow(delta);
@ -168,13 +206,31 @@ Buffer::shift(size_t offset, size_t delta)
resized = true;
}
for (size_t i = this->length; i >= offset; i++) {
this->contents[i+delta] = this->contents[i];
}
if (this->length == 0) return 0;
memmove(this->contents+(offset+delta), this->contents+offset, this->length);
return resized;
}
bool
Buffer::shiftLeft(size_t offset, size_t delta)
{
auto resized = false;
for (size_t i = offset; i < this->length; i++) {
this->contents[i] = this->contents[i+delta];
}
return this->Trim() != 0;
}
uint8_t&
Buffer::operator[](size_t index)
{
return this->contents[index];
}
} // namespace klib

View File

@ -14,19 +14,24 @@ namespace klib {
class Buffer {
public:
Buffer();
Buffer(size_t);
Buffer(const char *);
explicit Buffer(size_t);
explicit Buffer(const char *);
~Buffer() { this->Reclaim(); }
uint8_t *Contents() { return this->contents; }
size_t Size() { return this->length; };
size_t Capacity() { return this->capacity; }
size_t Length() const { return this->length; };
size_t Capacity() const { return this->capacity; }
bool Append(const char *s);
bool Append(uint8_t *data, size_t datalen);
bool Append(uint8_t c);
bool Insert(size_t index, const char *s);
bool Insert(size_t index, uint8_t *data, size_t datalen);
bool Insert(size_t index, uint8_t c);
// bool Remove(size_t index, size_t length);
bool Remove(size_t index, size_t count);
bool Remove(size_t index); // remove single char
/* memory management */
void Resize(size_t newCapacity);
@ -34,15 +39,19 @@ public:
void Clear();
void Reclaim();
uint8_t &operator[](size_t index);
private:
size_t mustGrow(size_t delta);
bool shift(size_t offset, size_t delta);
bool shiftRight(size_t offset, size_t delta);
bool shiftLeft(size_t offset, size_t delta);
uint8_t *contents;
size_t length;
size_t capacity;
};
} // namespace klib
#endif //KGE_BUFFER_H

View File

@ -11,6 +11,19 @@ main()
std::cout << buffer.Contents() << std::endl;
buffer.Insert(1, (uint8_t *)"el", 2);
buffer.Append('!');
std::cout << buffer.Contents() << std::endl;
buffer.Remove(buffer.Length()-1);
buffer.Remove(0, 5);
buffer.Insert(0, 'g');
buffer.Insert(1, (uint8_t *)"oodbye", 6);
buffer.Reclaim();
buffer.Append("and now for something completely different...");
std::cout << buffer.Contents() << std::endl;
return 0;
}