first pass at basic buffer functionality
This commit is contained in:
parent
d1f84be120
commit
f49a41bd77
106
Buffer.cc
106
Buffer.cc
|
@ -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
|
||||||
|
|
19
Buffer.h
19
Buffer.h
|
@ -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;
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "Buffer.h"
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
Buffer buffer("hlo, world");
|
||||||
|
|
||||||
|
std::cout << buffer.Contents() << std::endl;
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue