Created
April 1, 2019 01:53
-
-
Save rwy7/8b4cbac33610fea16d952a1d292d2e9d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if !defined(OMR_BYTEBUFFER_HPP_) | |
#define OMR_BYTEBUFFER_HPP_ | |
#include <cstdint> | |
#include <cstddef> | |
#include <cstdlib> | |
#include <cstring> | |
#include <cstdio> | |
namespace OMR { | |
class ByteBuffer { | |
public: | |
/// disown the byte array. | |
std::uint8_t* release() { | |
std::uint8_t* data = _data; | |
_data = nullptr; | |
_capacity = 0; | |
_size = 0; | |
return data; | |
} | |
std::size_t size() const { return _size; } | |
std::size_t capacity() const { return _capacity; } | |
bool reserve(std::size_t capacity) { | |
if (capacity <= _capacity) { | |
return true; | |
} | |
return resize(capacity); | |
} | |
void clear() { | |
_capacity = 0; | |
if (_data != nullptr) { | |
std::free(_data); | |
_data = nullptr; | |
} | |
} | |
bool resize(std::size_t capacity) { | |
if (capacity == 0) { | |
clear(); | |
return true; | |
} | |
_data = (std::uint8_t*)std::realloc(_data, capacity); | |
if (_data != nullptr) { | |
_capacity = capacity; | |
return true; | |
} | |
return false; | |
} | |
template <typename T> | |
bool emit(const T& value) { | |
if (!grow(_size + sizeof(T))) { | |
return false; | |
} | |
std::memcpy(end(), (void*)&value, sizeof(T)); | |
#if 1 | |
fprintf(stderr, "emit: nbytes=%zu\n", sizeof(T)); | |
for (std::size_t i = 0; i < sizeof(T); ++i) { | |
fprintf(stderr, " emit: [%zu:%p]=%hhu\n", i, end() + i, end()[i]); | |
} | |
#endif // | |
_size += sizeof(T); | |
return true; | |
} | |
std::uint8_t* start() { return _data; } | |
std::uint8_t* end() { return _data + _size; } | |
const std::uint8_t* start() const { return _data; } | |
const std::uint8_t* end() const { return _data + _size; } | |
private: | |
bool grow(std::size_t mincapa) { | |
std::size_t newcapa = _capacity != 0 ? _capacity : 128; | |
while (newcapa < mincapa) { | |
newcapa *= 2; | |
} | |
return reserve(newcapa); | |
} | |
std::uint8_t* _data = nullptr; | |
std::size_t _size = 0; | |
std::size_t _capacity = 0; | |
}; | |
template <typename T> | |
ByteBuffer& operator<<(ByteBuffer& buffer, const T& value) { | |
buffer.emit(value); | |
return buffer; | |
} | |
} // namespace OMR | |
#endif // OMR_BYTEBUFFER_HPP_ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment