diff options
author | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
---|---|---|
committer | Kae <80987908+Novaenia@users.noreply.github.com> | 2023-06-20 14:33:09 +1000 |
commit | 6352e8e3196f78388b6c771073f9e03eaa612673 (patch) | |
tree | e23772f79a7fbc41bc9108951e9e136857484bf4 /source/core/StarByteArray.hpp | |
parent | 6741a057e5639280d85d0f88ba26f000baa58f61 (diff) |
everything everywhere
all at once
Diffstat (limited to 'source/core/StarByteArray.hpp')
-rw-r--r-- | source/core/StarByteArray.hpp | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/source/core/StarByteArray.hpp b/source/core/StarByteArray.hpp new file mode 100644 index 0000000..051895f --- /dev/null +++ b/source/core/StarByteArray.hpp @@ -0,0 +1,259 @@ +#ifndef STAR_BYTE_ARRAY_H +#define STAR_BYTE_ARRAY_H + +#include "StarHash.hpp" +#include "StarException.hpp" +#include "StarFormat.hpp" + +namespace Star { + +STAR_CLASS(ByteArray); + +// Class to hold an array of bytes. Contains an internal buffer that may be +// larger than what is reported by size(), to avoid repeated allocations when a +// ByteArray grows. +class ByteArray { +public: + typedef char value_type; + typedef char* iterator; + typedef char const* const_iterator; + + // Constructs a byte array from a given c string WITHOUT including the + // trailing '\0' + static ByteArray fromCString(char const* str); + // Same, but includes the trailing '\0' + static ByteArray fromCStringWithNull(char const* str); + static ByteArray withReserve(size_t capacity); + + ByteArray(); + ByteArray(size_t dataSize, char c); + ByteArray(char const* data, size_t dataSize); + ByteArray(ByteArray const& b); + ByteArray(ByteArray&& b) noexcept; + ~ByteArray(); + + ByteArray& operator=(ByteArray const& b); + ByteArray& operator=(ByteArray&& b) noexcept; + + char const* ptr() const; + char* ptr(); + + size_t size() const; + // Maximum size before realloc + size_t capacity() const; + // Is zero size + bool empty() const; + + // Sets size to 0. + void clear(); + // Clears and resets buffer to empty. + void reset(); + + void reserve(size_t capacity); + + void resize(size_t size); + // resize, filling new space with given byte if it exists. + void resize(size_t size, char f); + + // fill array with byte. + void fill(char c); + // fill array and resize to new size. + void fill(size_t size, char c); + + void append(ByteArray const& b); + void append(char const* data, size_t len); + void appendByte(char b); + + void copyTo(char* data, size_t len) const; + void copyTo(char* data) const; + + // Copy from ByteArray starting at pos, to data, with size len. + void copyTo(char* data, size_t pos, size_t len) const; + // Copy from data pointer to ByteArray at pos with size len. + // Resizes if needed. + void writeFrom(char const* data, size_t pos, size_t len); + + ByteArray sub(size_t b, size_t s) const; + ByteArray left(size_t s) const; + ByteArray right(size_t s) const; + + void trimLeft(size_t s); + void trimRight(size_t s); + + // returns location of first character that is different than the given + // ByteArray. + size_t diffChar(ByteArray const& b) const; + // returns -1 if this < b, 0 if this == b, 1 if this > b + int compare(ByteArray const& b) const; + + template <typename Combiner> + ByteArray combineWith(Combiner&& combine, ByteArray const& rhs, bool extend = false); + + ByteArray andWith(ByteArray const& rhs, bool extend = false); + ByteArray orWith(ByteArray const& rhs, bool extend = false); + ByteArray xorWith(ByteArray const& rhs, bool extend = false); + + iterator begin(); + iterator end(); + + const_iterator begin() const; + const_iterator end() const; + + void insert(size_t pos, char byte); + iterator insert(const_iterator pos, char byte); + void push_back(char byte); + + char& operator[](size_t i); + char operator[](size_t i) const; + char at(size_t i) const; + + bool operator<(ByteArray const& b) const; + bool operator==(ByteArray const& b) const; + bool operator!=(ByteArray const& b) const; + +private: + char* m_data; + size_t m_capacity; + size_t m_size; +}; + +template <> +struct hash<ByteArray> { + size_t operator()(ByteArray const& b) const; +}; + +std::ostream& operator<<(std::ostream& os, ByteArray const& b); + +inline void ByteArray::clear() { + resize(0); +} + +inline void ByteArray::resize(size_t size) { + reserve(size); + m_size = size; +} + +inline void ByteArray::append(ByteArray const& b) { + append(b.ptr(), b.size()); +} + +inline void ByteArray::append(const char* data, size_t len) { + resize(m_size + len); + std::memcpy(m_data + m_size - len, data, len); +} + +inline void ByteArray::appendByte(char b) { + resize(m_size + 1); + m_data[m_size - 1] = b; +} + +inline bool ByteArray::empty() const { + return m_size == 0; +} + +inline char const* ByteArray::ptr() const { + return m_data; +} + +inline char* ByteArray::ptr() { + return m_data; +} + +inline size_t ByteArray::size() const { + return m_size; +} + +inline size_t ByteArray::capacity() const { + return m_capacity; +} + +inline void ByteArray::copyTo(char* data, size_t len) const { + len = min(m_size, len); + std::memcpy(data, m_data, len); +} + +inline void ByteArray::copyTo(char* data) const { + copyTo(data, m_size); +} + +inline void ByteArray::copyTo(char* data, size_t pos, size_t len) const { + if (len == 0 || pos >= m_size) + return; + + len = min(m_size - pos, len); + std::memcpy(data, m_data + pos, len); +} + +inline void ByteArray::writeFrom(const char* data, size_t pos, size_t len) { + if (pos + len > m_size) + resize(pos + len); + + std::memcpy(m_data + pos, data, len); +} + +template <typename Combiner> +ByteArray ByteArray::combineWith(Combiner&& combine, ByteArray const& rhs, bool extend) { + ByteArray const* smallerArray = &rhs; + ByteArray const* largerArray = this; + + if (m_size < rhs.size()) + swap(smallerArray, largerArray); + + ByteArray res; + res.resize(smallerArray->size()); + + for (size_t i = 0; i < smallerArray->size(); ++i) + res[i] = combine((*smallerArray)[i], (*largerArray)[i]); + + if (extend) { + res.resize(largerArray->size()); + for (size_t i = smallerArray->size(); i < largerArray->size(); ++i) + res[i] = (*largerArray)[i]; + } + + return res; +} + +inline ByteArray::iterator ByteArray::begin() { + return m_data; +} + +inline ByteArray::iterator ByteArray::end() { + return m_data + m_size; +} + +inline ByteArray::const_iterator ByteArray::begin() const { + return m_data; +} + +inline ByteArray::const_iterator ByteArray::end() const { + return m_data + m_size; +} + +inline char& ByteArray::operator[](size_t i) { + starAssert(i < m_size); + return m_data[i]; +} + +inline char ByteArray::operator[](size_t i) const { + starAssert(i < m_size); + return m_data[i]; +} + +inline char ByteArray::at(size_t i) const { + if (i >= m_size) + throw OutOfRangeException(strf("Out of range in ByteArray::at(%s)", i)); + + return m_data[i]; +} + +inline size_t hash<ByteArray>::operator()(ByteArray const& b) const { + PLHasher hash; + for (size_t i = 0; i < b.size(); ++i) + hash.put(b[i]); + return hash.hash(); +} + +} + +#endif |