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 >> 16;
x |= x >> 32; 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 bool
Buffer::Append(uint8_t *data, size_t datalen) Buffer::Append(uint8_t *data, size_t datalen)
{ {
@ -78,12 +86,23 @@ Buffer::Append(uint8_t c)
return this->Append(&c, 1); 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 bool
Buffer::Insert(size_t index, uint8_t *data, size_t datalen) 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); memcpy(this->contents + index, data, datalen);
this->length += datalen;
return resized; 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 void
Buffer::Resize(size_t newCapacity) Buffer::Resize(size_t newCapacity)
{ {
@ -103,6 +139,7 @@ Buffer::Resize(size_t newCapacity)
uint8_t *newContents = new uint8_t[newCapacity]; uint8_t *newContents = new uint8_t[newCapacity];
memset(newContents, 0, newCapacity);
if (this->length > 0) { if (this->length > 0) {
memcpy(newContents, this->contents, this->length); memcpy(newContents, this->contents, this->length);
} }
@ -140,8 +177,9 @@ Buffer::Clear()
void void
Buffer::Reclaim() Buffer::Reclaim()
{ {
this->Clear();
delete this->contents; delete this->contents;
this->length = 0;
this->capacity = 0; this->capacity = 0;
} }
@ -158,7 +196,7 @@ Buffer::mustGrow(size_t delta)
bool bool
Buffer::shift(size_t offset, size_t delta) Buffer::shiftRight(size_t offset, size_t delta)
{ {
auto resized = false; auto resized = false;
auto newCap = this->mustGrow(delta); auto newCap = this->mustGrow(delta);
@ -168,13 +206,31 @@ Buffer::shift(size_t offset, size_t delta)
resized = true; resized = true;
} }
if (this->length == 0) return 0;
for (size_t i = this->length; i >= offset; i++) {
this->contents[i+delta] = this->contents[i];
}
memmove(this->contents+(offset+delta), this->contents+offset, this->length);
return resized; 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 } // namespace klib

View File

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

View File

@ -11,6 +11,19 @@ main()
std::cout << buffer.Contents() << std::endl; std::cout << buffer.Contents() << std::endl;
buffer.Insert(1, (uint8_t *)"el", 2); buffer.Insert(1, (uint8_t *)"el", 2);
buffer.Append('!');
std::cout << buffer.Contents() << std::endl; 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;
} }