first pass at basic buffer functionality

This commit is contained in:
Kyle Isom 2023-10-09 04:49:38 -07:00
parent d1f84be120
commit f49a41bd77
4 changed files with 127 additions and 13 deletions

106
Buffer.cc
View File

@ -6,6 +6,35 @@
#include "Buffer.h" #include "Buffer.h"
namespace kge { namespace kge {
constexpr size_t defaultCapacity = 32;
constexpr size_t maxReasonableLine = 8192;
Buffer::Buffer()
: contents(nullptr), length(0), capacity(0)
{
this->Resize(defaultCapacity);
}
Buffer::Buffer(size_t initialCapacity)
: contents(nullptr), length(0), capacity(0)
{
this->Resize(initialCapacity);
}
Buffer::Buffer(const char *data)
: contents(nullptr), length(0), capacity(0)
{
size_t datalen = strnlen(data, maxReasonableLine);
this->Append(data, datalen);
}
uint8_t * uint8_t *
Buffer::Contents() Buffer::Contents()
{ {
@ -15,25 +44,43 @@ Buffer::Contents()
bool bool
Buffer::Append(uint8_t *data, size_t datalen) Buffer::Append(uint8_t *data, size_t datalen)
{ {
return false; auto resized = false;
auto newCap = this->mustGrow(datalen);
if (newCap > 0) {
this->Resize(newCap);
resized = true;
}
memcpy(this->contents + this->length, data, datalen);
this->length += datalen;
return resized;
} }
bool bool
Buffer::Append(uint8_t c) Buffer::Append(uint8_t c)
{ {
return false; return this->Append(&c, 1);
} }
bool bool
Buffer::Insert(size_t index, uint8_t *data, size_t datalen) Buffer::Insert(size_t index, uint8_t *data, size_t datalen)
{ {
return false; auto resized = this->shift(index, datalen);
if (newCap > 0) {
this->Resize(newCap);
resized = true;
}
memcpy(this->contents + index, data, datalen);
return resized;
} }
bool bool
Buffer::Insert(size_t index, uint8_t c) Buffer::Insert(size_t index, uint8_t c)
{ {
return false; return this->Insert(index, &c, 1);
} }
size_t size_t
@ -51,8 +98,14 @@ Buffer::Resize(size_t newCapacity)
uint8_t *newContents = new uint8_t[newCapacity]; uint8_t *newContents = new uint8_t[newCapacity];
memcpy(newContents, this->contents, this->length); if (this->length > 0) {
delete this->contents; memcpy(newContents, this->contents, this->length);
}
if (this->contents != nullptr) {
delete this->contents;
}
this->contents = newContents; this->contents = newContents;
this->capacity = newCapacity; this->capacity = newCapacity;
} }
@ -82,11 +135,44 @@ Buffer::Reclaim()
this->capacity = 0; this->capacity = 0;
} }
bool size_t
Buffer::mustGrow(size_t newLength) Buffer::mustGrow(size_t delta)
{ {
return (newLength + this->length) >= this->capacity; if ((delta + this->length) < this->capacity) {
return 0;
}
auto newCapacity = delta + this->length;
newCapacity--;
newCapacity |= newCapacity >> 1;
newCapacity |= newCapacity >> 2;
newCapacity |= newCapacity >> 4;
newCapacity |= newCapacity >> 8;
newCapacity |= newCapacity >> 16;
newCapacity |= newCapacity >> 32;
return newCapacity;
} }
} // kge bool
Buffer:shift(size_t offset, size_t delta)
{
auto resized = false;
auto newCap = this->mustGrow(delta);
if (newCap > 0) {
this->Resize(newCap);
resized = true;
}
for (size_t i = this->length; i >= offset; i++) {
this->contents[i+delta] = this->contents[i];
}
return resized;
}
} // kge

View File

@ -10,20 +10,33 @@
namespace kge { namespace kge {
class Buffer { class Buffer {
public: public:
uint8_t *Contents(); Buffer();
Buffer(size_t);
Buffer(const char *);
uint8_t *Contents() { return this->contents; }
size_t Size() { return this->size; };
size_t Capacity() { return this->capacity; }
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, 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);
size_t Size();
// bool Remove(size_t index, size_t length);
/* memory management */
void Resize(size_t newCapacity); void Resize(size_t newCapacity);
size_t Trim(); size_t Trim();
void Clear(); void Clear();
void Reclaim(); void Reclaim();
private: private:
bool mustGrow(size_t newLength); bool mustGrow(size_t delta);
bool shift(size_t offset, size_t delta);
uint8_t *contents; uint8_t *contents;
size_t length; size_t length;

12
BufferTest.cc Normal file
View File

@ -0,0 +1,12 @@
#include <iostream>
#include "Buffer.h"
int
main()
{
Buffer buffer("hlo, world");
std::cout << buffer.Contents() << std::endl;
}

View File

@ -56,6 +56,9 @@ target_include_directories(imgui PUBLIC
include_directories(ext/ ${SDL2_INCLUDE_DIRS}) include_directories(ext/ ${SDL2_INCLUDE_DIRS})
add_executable(BufferTest BufferTest.cc Buffer.cc)
add_test(BufferTest COMMAND BufferTest)
add_executable(kge add_executable(kge
kge.cc kge.cc
Buffer.cc Buffer.cc