Finish basic buffer implementation.
This commit is contained in:
parent
1bc5bc0b10
commit
f8041c2bfa
72
Buffer.cc
72
Buffer.cc
|
@ -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++) {
|
memmove(this->contents+(offset+delta), this->contents+offset, this->length);
|
||||||
this->contents[i+delta] = this->contents[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
||||||
|
|
21
Buffer.h
21
Buffer.h
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue