Documentation, usability updates, and removing debug code.
+ First pass at documenting the Buffer class. + Starting Arena documentation. + Various usability updates, such as overloading operators. + Remove debug traces.
This commit is contained in:
parent
0f1eff514d
commit
386869df44
5
Arena.cc
5
Arena.cc
|
@ -268,7 +268,8 @@ operator<<(std::ostream &os, Arena &arena)
|
|||
{
|
||||
auto cursor = arena.Store();
|
||||
char cursorString[33] = {0};
|
||||
snprintf(cursorString, 32, "%#016llx", cursor);
|
||||
snprintf(cursorString, 32, "%#016llx",
|
||||
(long long unsigned int)cursor);
|
||||
|
||||
os << "Arena<";
|
||||
switch (arena.Type()) {
|
||||
|
@ -328,4 +329,4 @@ Arena::Write(const char *path)
|
|||
}
|
||||
|
||||
|
||||
} // namespace klib
|
||||
} // namespace klib
|
||||
|
|
35
Arena.h
35
Arena.h
|
@ -1,9 +1,29 @@
|
|||
/// @file Arena.h
|
||||
/// @author K. Isom
|
||||
/// @brief Memory management using an arena.
|
||||
/// @section DESCRIPTION
|
||||
///
|
||||
/// \file Arena.h
|
||||
/// \author K. Isom
|
||||
/// \date 2023-10-06
|
||||
/// \brief Memory management using an arena.
|
||||
///
|
||||
/// \section COPYRIGHT
|
||||
/// Copyright 2023 K. Isom <kyle@imap.cc>
|
||||
///
|
||||
/// Permission to use, copy, modify, and/or distribute this software for
|
||||
/// any purpose with or without fee is hereby granted, provided that the
|
||||
/// above copyright notice and this permission notice appear in all copies.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
/// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
/// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
||||
/// BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
||||
/// OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
/// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
/// ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
/// SOFTWARE.
|
||||
///
|
||||
/// \section DESCRIPTION
|
||||
/// Arena defines a memory management backend for pre-allocating memory.
|
||||
|
||||
|
||||
#ifndef KIMODEM_ARENA_H
|
||||
#define KIMODEM_ARENA_H
|
||||
|
||||
|
@ -17,13 +37,20 @@
|
|||
namespace klib {
|
||||
|
||||
|
||||
/// \enum ArenaType describes the type of #Arena.
|
||||
enum ArenaType : uint8_t {
|
||||
/// ARENA_UNINIT is an unintialized arena.
|
||||
ARENA_UNINIT,
|
||||
/// ARENA_STATIC is an arena backed by a static block of memory.
|
||||
ARENA_STATIC,
|
||||
/// ARENA_ALLOC is an arena backed by allocated memory.
|
||||
ARENA_ALLOC,
|
||||
/// ARENA_MMAP is an arena backed by a memory-mapped file.
|
||||
ARENA_MMAP,
|
||||
};
|
||||
|
||||
|
||||
/// Arena is the class that implements a memory arena.
|
||||
class Arena {
|
||||
public:
|
||||
Arena();
|
||||
|
|
122
Buffer.cc
122
Buffer.cc
|
@ -1,6 +1,24 @@
|
|||
//
|
||||
// Created by kyle on 2023-10-09.
|
||||
//
|
||||
///
|
||||
/// \file Buffer.cc
|
||||
/// \author K. Isom <kyle@imap.cc>
|
||||
/// \date 2023-10-09
|
||||
///
|
||||
/// \section COPYRIGHT
|
||||
/// Copyright 2023 K. Isom <kyle@imap.cc>
|
||||
///
|
||||
/// Permission to use, copy, modify, and/or distribute this software for
|
||||
/// any purpose with or without fee is hereby granted, provided that the
|
||||
/// above copyright notice and this permission notice appear in all copies.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
/// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
/// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
||||
/// BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
||||
/// OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
/// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
/// ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
/// SOFTWARE.
|
||||
///
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
@ -24,8 +42,6 @@ nearestPower(size_t x)
|
|||
return 0;
|
||||
}
|
||||
|
||||
std::cout << "x -> ";
|
||||
|
||||
x--;
|
||||
|
||||
x |= x >> 1;
|
||||
|
@ -35,28 +51,26 @@ nearestPower(size_t x)
|
|||
x |= x >> 16;
|
||||
x |= x >> 32;
|
||||
|
||||
std::cout << x + 1 << std::endl;
|
||||
|
||||
return x + 1;
|
||||
}
|
||||
|
||||
|
||||
Buffer::Buffer()
|
||||
: contents(nullptr), length(0), capacity(0)
|
||||
: contents(nullptr), length(0), capacity(0), autoTrim(true)
|
||||
{
|
||||
this->Resize(defaultCapacity);
|
||||
}
|
||||
|
||||
|
||||
Buffer::Buffer(size_t initialCapacity)
|
||||
: contents(nullptr), length(0), capacity(0)
|
||||
: contents(nullptr), length(0), capacity(0), autoTrim(true)
|
||||
{
|
||||
this->Resize(initialCapacity);
|
||||
}
|
||||
|
||||
|
||||
Buffer::Buffer(const char *data)
|
||||
: contents(nullptr), length(0), capacity(0)
|
||||
: contents(nullptr), length(0), capacity(0), autoTrim(true)
|
||||
{
|
||||
size_t datalen = strnlen(data, maxReasonableLine);
|
||||
|
||||
|
@ -64,6 +78,13 @@ Buffer::Buffer(const char *data)
|
|||
}
|
||||
|
||||
|
||||
Buffer::Buffer(const std::string s)
|
||||
: contents(nullptr), length(0), capacity(0), autoTrim(true)
|
||||
{
|
||||
this->Append(s);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Buffer::Append(const char *s)
|
||||
{
|
||||
|
@ -72,8 +93,16 @@ Buffer::Append(const char *s)
|
|||
return this->Append((uint8_t *) s, slen);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Buffer::Append(uint8_t *data, size_t datalen)
|
||||
Buffer::Append(const std::string s)
|
||||
{
|
||||
return this->Append((const uint8_t *) s.c_str(), s.size());
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Buffer::Append(const uint8_t *data, const size_t datalen)
|
||||
{
|
||||
auto resized = false;
|
||||
auto newCap = this->mustGrow(datalen);
|
||||
|
@ -89,15 +118,16 @@ Buffer::Append(uint8_t *data, size_t datalen)
|
|||
return resized;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Buffer::Append(uint8_t c)
|
||||
Buffer::Append(const uint8_t c)
|
||||
{
|
||||
return this->Append(&c, 1);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Buffer::Insert(size_t index, const char *s)
|
||||
Buffer::Insert(const size_t index, const char *s)
|
||||
{
|
||||
size_t slen = strnlen(s, maxReasonableLine);
|
||||
|
||||
|
@ -106,7 +136,14 @@ Buffer::Insert(size_t index, const char *s)
|
|||
|
||||
|
||||
bool
|
||||
Buffer::Insert(size_t index, uint8_t *data, size_t datalen)
|
||||
Buffer::Insert(const size_t index, const std::string s)
|
||||
{
|
||||
return this->Insert(index, (const uint8_t *) s.c_str(), s.size());
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Buffer::Insert(const size_t index, const uint8_t *data, const size_t datalen)
|
||||
{
|
||||
auto resized = this->shiftRight(index, datalen);
|
||||
|
||||
|
@ -115,15 +152,16 @@ Buffer::Insert(size_t index, uint8_t *data, size_t datalen)
|
|||
return resized;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Buffer::Insert(size_t index, uint8_t c)
|
||||
Buffer::Insert(const size_t index, const uint8_t c)
|
||||
{
|
||||
return this->Insert(index, &c, 1);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Buffer::Remove(size_t index, size_t count)
|
||||
Buffer::Remove(const size_t index, const size_t count)
|
||||
{
|
||||
auto resized = this->shiftLeft(index, count);
|
||||
|
||||
|
@ -180,6 +218,7 @@ Buffer::Clear()
|
|||
if (this->length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(this->contents, 0, this->length);
|
||||
this->length = 0;
|
||||
}
|
||||
|
@ -187,23 +226,16 @@ Buffer::Clear()
|
|||
void
|
||||
Buffer::Reclaim()
|
||||
{
|
||||
std::cout << "clear" << std::endl;
|
||||
this->Clear();
|
||||
|
||||
std::cout << "nullptr check" << std::endl;
|
||||
if (this->contents == nullptr) {
|
||||
std::cout << "assert checks" << std::endl;
|
||||
assert(this->length == 0);
|
||||
assert(this->capacity == 0);
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "delete " << this->Capacity() << "B" << std::endl;
|
||||
this->HexDump(std::cout);
|
||||
delete this->contents;
|
||||
std::cout << "reset contents" << std::endl;
|
||||
this->contents = nullptr;
|
||||
std::cout << "reset capacity" << std::endl;
|
||||
this->capacity = 0;
|
||||
}
|
||||
|
||||
|
@ -223,13 +255,13 @@ void
|
|||
Buffer::HexDump(std::ostream &os)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
size_t index = 0;
|
||||
size_t index = 0;
|
||||
|
||||
os << std::hex;
|
||||
os << std::setfill('0');
|
||||
|
||||
for (index = 0; index < this->length; index++) {
|
||||
bool eol = (index % 16) == 0;
|
||||
bool eol = (index % 16) == 0;
|
||||
if (eol && (index > 0)) {
|
||||
os << std::endl;
|
||||
}
|
||||
|
@ -240,7 +272,7 @@ Buffer::HexDump(std::ostream &os)
|
|||
os << std::setw(2);
|
||||
}
|
||||
|
||||
os << (unsigned short)this->contents[index];
|
||||
os << (unsigned short) this->contents[index];
|
||||
|
||||
if ((index % 15) != 0 || (index == 0)) {
|
||||
os << " ";
|
||||
|
@ -268,7 +300,8 @@ Buffer::shiftRight(size_t offset, size_t delta)
|
|||
|
||||
if (this->length == 0) return 0;
|
||||
|
||||
memmove(this->contents + (offset + delta), this->contents + offset, this->length);
|
||||
memmove(this->contents + (offset + delta), this->contents + offset,
|
||||
this->length);
|
||||
return resized;
|
||||
}
|
||||
|
||||
|
@ -276,21 +309,44 @@ Buffer::shiftRight(size_t offset, size_t delta)
|
|||
bool
|
||||
Buffer::shiftLeft(size_t offset, size_t delta)
|
||||
{
|
||||
// for (size_t i = offset; i < this->length; i++) {
|
||||
// this->contents[i] = this->contents[i+delta];
|
||||
// }
|
||||
memmove(this->contents + offset, this->contents + (offset + delta),
|
||||
this->length);
|
||||
|
||||
memmove(this->contents + offset, this->contents + (offset + delta), this->length);
|
||||
|
||||
return this->Trim() != 0;
|
||||
if (this->AutoTrimIsEnabled()) {
|
||||
return this->Trim() != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
uint8_t &
|
||||
Buffer::operator[](size_t index)
|
||||
{
|
||||
if (index > this->length) {
|
||||
throw std::range_error("array index out of bounds");
|
||||
}
|
||||
return this->contents[index];
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
operator==(const Buffer &lhs, const Buffer &rhs)
|
||||
{
|
||||
if (lhs.length != rhs.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return memcmp(lhs.contents, rhs.contents, rhs.length) == 0;
|
||||
}
|
||||
|
||||
|
||||
std::ostream &
|
||||
operator<<(std::ostream &os, const Buffer &buf)
|
||||
{
|
||||
// std::string s((const char *)buf.Contents(), buf.Length());
|
||||
os << const_cast<uint8_t *>(buf.Contents());
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
} // namespace klib
|
||||
|
|
233
Buffer.h
233
Buffer.h
|
@ -1,6 +1,30 @@
|
|||
//
|
||||
// Created by kyle on 2023-10-09.
|
||||
//
|
||||
///
|
||||
/// \file Buffer.hcc
|
||||
/// \author K. Isom <kyle@imap.cc>
|
||||
/// \date 2023-10-09
|
||||
/// \brief Buffer implements basic line buffers.
|
||||
///
|
||||
/// \section COPYRIGHT
|
||||
/// Copyright 2023 K. Isom <kyle@imap.cc>
|
||||
///
|
||||
/// Permission to use, copy, modify, and/or distribute this software for
|
||||
/// any purpose with or without fee is hereby granted, provided that the
|
||||
/// above copyright notice and this permission notice appear in all copies.
|
||||
///
|
||||
/// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
/// WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
/// WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
||||
/// BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
||||
/// OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
/// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
/// ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
/// SOFTWARE.
|
||||
///
|
||||
/// \section DESCRIPTION
|
||||
/// Buffer implements a basic uint8_t line buffer that is intended for use in text
|
||||
/// editing. It allocates memory in powers of two, and will grow or shrink
|
||||
/// as needed.
|
||||
///
|
||||
|
||||
#ifndef KGE_BUFFER_H
|
||||
#define KGE_BUFFER_H
|
||||
|
@ -11,50 +35,197 @@
|
|||
|
||||
namespace klib {
|
||||
|
||||
|
||||
/// Buffer is a basic line buffer.
|
||||
///
|
||||
/// The buffer manages its own internal memory, growing and shrinking
|
||||
/// as needed. Its capacity is separate from its length; the optimal
|
||||
/// capacity is determined as the nearest power of two that is greater
|
||||
/// than the length of the buffer. For example, if the buffer has a
|
||||
/// length of 5 bytes, 8 bytes will be allocated. If the buffer is 9
|
||||
/// bytes, 16 bytes will be allocated.
|
||||
///
|
||||
/// The #Append and #Insert methods will call #Resize as necessary to grow
|
||||
/// the buffer. Similarly the #Remove methods will call #Trim to reclaim some
|
||||
/// memory if possible, but only if #AutoTrimIsEnabled (it is by default).
|
||||
class Buffer {
|
||||
public:
|
||||
/// A Buffer can be constructed empty, with no memory allocated (yet).
|
||||
Buffer();
|
||||
explicit Buffer(size_t);
|
||||
explicit Buffer(const char *);
|
||||
~Buffer() { this->Reclaim(); }
|
||||
|
||||
uint8_t *Contents() { return this->contents; }
|
||||
size_t Length() const { return this->length; };
|
||||
size_t Capacity() const { return this->capacity; }
|
||||
/// A Buffer can be constructed with an explicit capacity.
|
||||
///
|
||||
/// \param initialCapacity The initial allocation size for the buffer.
|
||||
explicit Buffer(size_t initialCapacity);
|
||||
|
||||
bool Append(const char *s);
|
||||
bool Append(uint8_t *data, size_t datalen);
|
||||
bool Append(uint8_t c);
|
||||
/// A Buffer can be initialized with a starting C-style string.
|
||||
explicit Buffer(const char *s);
|
||||
|
||||
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);
|
||||
/// A Buffer can be initialized with a starting string.
|
||||
explicit Buffer(const std::string s);
|
||||
|
||||
bool Remove(size_t index, size_t count);
|
||||
bool Remove(size_t index); // remove single char
|
||||
~Buffer()
|
||||
{ this->Reclaim(); }
|
||||
|
||||
/// Contents returns the Buffer's contents.
|
||||
uint8_t *Contents() const
|
||||
{ return this->contents; }
|
||||
|
||||
/// Length returns the length of the data currently stored in the
|
||||
/// buffer.
|
||||
size_t Length() const
|
||||
{ return this->length; };
|
||||
|
||||
/// Capacity returns the amount of memory allocated to the Buffer.
|
||||
size_t Capacity() const
|
||||
{ return this->capacity; }
|
||||
|
||||
/// Append copies in a C-style string to the end of the buffer.
|
||||
///
|
||||
/// \param s The string to append.
|
||||
/// \return True if the Buffer was resized.
|
||||
bool Append(const char *s);
|
||||
|
||||
/// Append copies in a string to the end of the buffer.
|
||||
///
|
||||
/// \param s The string to append.
|
||||
/// \return True if the Buffer was resized.
|
||||
bool Append(const std::string s);
|
||||
|
||||
/// Append copies in a byte buffer to the end of the buffer.
|
||||
///
|
||||
/// \param data The byte buffer to insert.
|
||||
/// \param datalen The length of the byte buffer.
|
||||
/// \return True if the Buffer was resized.
|
||||
bool Append(const uint8_t *data, const size_t datalen);
|
||||
|
||||
/// Append copies a single character to the end of the buffer.
|
||||
///
|
||||
/// \param c The character to append.
|
||||
/// \return True if the Buffer was resized.
|
||||
bool Append(const uint8_t c);
|
||||
|
||||
/// Insert copies a C-style string into the buffer at index.
|
||||
///
|
||||
/// \param index The index to insert the string at.
|
||||
/// \param s The string to insert.
|
||||
/// \return True if the Buffer was resized.
|
||||
bool Insert(const size_t index, const char *s);
|
||||
|
||||
/// Insert copies a string into the buffer at index.
|
||||
///
|
||||
/// \param index The index the string should be inserted at.
|
||||
/// \param s The string to insert.
|
||||
/// \return True if the Buffer was resized.
|
||||
bool Insert(const size_t index, const std::string s);
|
||||
|
||||
/// Insert copies a uint8_t buffer into the buffer at index.
|
||||
///
|
||||
/// \param index The index to insert the buffer at.
|
||||
/// \param data The buffer to insert.
|
||||
/// \param datalen The size of the data buffer.
|
||||
/// \return True if the Buffer was resized.
|
||||
bool
|
||||
Insert(const size_t index, const uint8_t *data, const size_t datalen);
|
||||
|
||||
/// Insert copies a character into the buffer at index.
|
||||
///
|
||||
/// \param index The index to insert the character at.
|
||||
/// \param c The character to insert.
|
||||
/// \return True if the Buffer was resized.
|
||||
bool Insert(const size_t index, const uint8_t c);
|
||||
|
||||
/// Remove removes `count` bytes from the buffer at `index`.
|
||||
///
|
||||
/// \param index The starting index to remove bytes from.
|
||||
/// \param count The number of bytes to remove.
|
||||
/// \return True if the Buffer was resized.
|
||||
bool Remove(const size_t index, const size_t count);
|
||||
|
||||
/// Remove removes a single byte from the buffer.
|
||||
///
|
||||
/// \param index The index pointing to the byte to be removed.
|
||||
/// \return True if the Buffer was resized.
|
||||
bool Remove(size_t index); // remove single char
|
||||
|
||||
/* memory management */
|
||||
void Resize(size_t newCapacity);
|
||||
size_t Trim();
|
||||
void Clear();
|
||||
void Reclaim();
|
||||
|
||||
void HexDump(std::ostream &os);
|
||||
/// Resize changes the capacity of the buffer to `newCapacity`.
|
||||
///
|
||||
/// If newCapacity is less than the length of the Buffer, it
|
||||
/// will remove enough bytes from the end to make this happen.
|
||||
///
|
||||
/// \param newCapacity The new capacity for the Buffer.
|
||||
void Resize(size_t newCapacity);
|
||||
|
||||
/// Trim will resize the Buffer to an appropriate size based on
|
||||
/// its length.
|
||||
///
|
||||
/// \return The new capacity of the Buffer.
|
||||
size_t Trim();
|
||||
|
||||
/// DisableAutoTrim prevents the #Buffer from automatically
|
||||
/// trimming memory after a call to #Remove.
|
||||
void DisableAutoTrim()
|
||||
{ this->autoTrim = false; }
|
||||
|
||||
/// EnableAutoTrim enables automatically trimming memory after
|
||||
/// calls to #Remove.
|
||||
void EnableAutoTrim()
|
||||
{ this->autoTrim = true; }
|
||||
|
||||
/// AutoTrimIsEnabled returns true if autotrim is enabled.
|
||||
///
|
||||
/// \return #Remove will call Trim.
|
||||
bool AutoTrimIsEnabled()
|
||||
{ return this->autoTrim; }
|
||||
|
||||
/// Clear removes the data stored in the buffer. It will not
|
||||
/// call #Trim; the capacity of the buffer will not be altered.
|
||||
void Clear();
|
||||
|
||||
/// Reclaim the memory in the buffer: the buffer will call #Clear,
|
||||
/// followed by deleting any allocated memory.
|
||||
void Reclaim();
|
||||
|
||||
/// HexDump dumps the data in the buffer to the output stream;
|
||||
/// it is intended as a debugging tool.
|
||||
///
|
||||
/// \param os The output stream to write to.
|
||||
void HexDump(std::ostream &os);
|
||||
|
||||
/// This operator allows the data in the buffer to be accessed
|
||||
/// as if it were an array. If the index is out of bounds, it
|
||||
/// will throw a range_error.
|
||||
///
|
||||
/// \throws std::range_error.
|
||||
///
|
||||
/// \param index The index to retrieve.
|
||||
/// \return
|
||||
uint8_t &operator[](size_t index);
|
||||
|
||||
/// Two buffers are equal if their lengths are the same and
|
||||
/// their contents are the same. Equality is irrespective of
|
||||
/// their capacities.
|
||||
friend bool operator==(const Buffer &lhs, const Buffer &rhs);
|
||||
|
||||
uint8_t &operator[](size_t index);
|
||||
private:
|
||||
size_t mustGrow(size_t delta) const;
|
||||
bool shiftRight(size_t offset, size_t delta);
|
||||
bool shiftLeft(size_t offset, size_t delta);
|
||||
size_t mustGrow(size_t delta) const;
|
||||
|
||||
uint8_t *contents;
|
||||
size_t length;
|
||||
size_t capacity;
|
||||
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;
|
||||
bool autoTrim;
|
||||
};
|
||||
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const Buffer &buf);
|
||||
inline bool operator!=(const Buffer &lhs, const Buffer &rhs) { return !(lhs == rhs); };
|
||||
|
||||
} // namespace klib
|
||||
|
||||
#endif //KGE_BUFFER_H
|
||||
|
||||
#endif // KGE_BUFFER_H
|
||||
|
|
|
@ -4,7 +4,7 @@ find_package(Doxygen)
|
|||
if (${DOXYGEN_FOUND})
|
||||
|
||||
doxygen_add_docs(klib_docs
|
||||
${HEADER_FILES} ${SOURCE_FILES}
|
||||
USE_STAMP_FILE)
|
||||
${HEADER_FILES} ${SOURCE_FILES})
|
||||
# USE_STAMP_FILE)
|
||||
|
||||
endif ()
|
4
Test.cc
4
Test.cc
|
@ -33,10 +33,10 @@ AssertionFailed::AssertionFailed(std::string message) : msg(message)
|
|||
}
|
||||
|
||||
char *
|
||||
AssertionFailed::what() const noexcept
|
||||
AssertionFailed::what()
|
||||
{
|
||||
return const_cast<char *>(this->msg.c_str());
|
||||
}
|
||||
|
||||
|
||||
} // namespace klib
|
||||
} // namespace klib
|
||||
|
|
2
Test.h
2
Test.h
|
@ -19,7 +19,7 @@ class AssertionFailed : public std::exception {
|
|||
public:
|
||||
explicit AssertionFailed(std::string message);
|
||||
|
||||
char *what() const noexcept override;
|
||||
char *what();
|
||||
|
||||
public:
|
||||
std::string msg;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
#include "Buffer.h"
|
||||
using namespace klib;
|
||||
|
||||
|
||||
int
|
||||
|
@ -9,35 +11,26 @@ main(int argc, char *argv[])
|
|||
(void) argc;
|
||||
(void) argv;
|
||||
|
||||
klib::Buffer buffer("hlo, world");
|
||||
Buffer buffer("hlo, world");
|
||||
|
||||
std::cout << buffer.Contents() << std::endl;
|
||||
std::cout << buffer << std::endl;
|
||||
|
||||
buffer.Insert(1, (uint8_t *) "el", 2);
|
||||
buffer.Append('!');
|
||||
|
||||
std::cout << buffer.Contents() << std::endl;
|
||||
std::cout << buffer << std::endl;
|
||||
|
||||
std::cout << "remove end" << std::endl;
|
||||
buffer.Remove(buffer.Length() - 1);
|
||||
|
||||
std::cout << "remove start" << std::endl;
|
||||
buffer.Remove(0, 5);
|
||||
|
||||
std::cout << "insert char" << std::endl;
|
||||
buffer.Insert(0, 'g');
|
||||
|
||||
std::cout << "insert chunk" << std::endl;
|
||||
buffer.Insert(1, (uint8_t *) "oodbye", 6);
|
||||
std::cout << "cruel" << std::endl;
|
||||
std::cout << buffer << std::endl;
|
||||
buffer.Insert(9, (uint8_t *)"cruel ", 6);
|
||||
std::cout << buffer.Contents() << std::endl;
|
||||
|
||||
std::cout << buffer << std::endl;
|
||||
buffer.HexDump(std::cout);
|
||||
|
||||
std::cout << "reclaim" << std::endl;
|
||||
buffer.Reclaim();
|
||||
|
||||
std::cout << "append" << std::endl;
|
||||
buffer.Append("and now for something completely different...");
|
||||
|
||||
std::cout << buffer.Contents() << std::endl;
|
||||
|
@ -47,6 +40,12 @@ main(int argc, char *argv[])
|
|||
buffer.Trim();
|
||||
std::cout << "Length: " << buffer.Length() << ", capacity " << buffer.Capacity() << std::endl;
|
||||
|
||||
Buffer buffer2("and now for something completely different...");
|
||||
assert(buffer == buffer2);
|
||||
|
||||
buffer2.Remove(buffer2.Length()-3, 3);
|
||||
std::cout << buffer << std::endl;
|
||||
assert(buffer != buffer2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue