PkmnLib/src/ScriptResolving/AngelScript/ByteCodeHandling/MemoryByteCodeStream.hpp

69 lines
2.2 KiB
C++

#ifndef PKMNLIB_MEMORYBYTECODESTREAM_HPP
#define PKMNLIB_MEMORYBYTECODESTREAM_HPP
#include <angelscript.h>
#include <vector>
class MemoryByteCodeStream : public IPkmnBinaryStream {
private:
uint8_t* non_null _out;
size_t _index = 0;
size_t _size = 0;
size_t _capacity = 0;
#define MEM_STEPS 256
public:
MemoryByteCodeStream()
: IPkmnBinaryStream(SIZE_MAX), _out((uint8_t*)malloc(MEM_STEPS * sizeof(uint8_t))), _capacity(MEM_STEPS){};
MemoryByteCodeStream(uint8_t* non_null in, size_t size) : IPkmnBinaryStream(SIZE_MAX), _out(in), _size(size) {}
uint8_t* non_null GetOut() const { return _out; }
size_t GetWrittenSize() const { return _size; }
void SetAngelScriptBound(size_t bound) noexcept { _angelScriptBound = bound; }
int Write(const void* non_null ptr, asUINT size) final {
if (size == 0)
return 0;
auto initialSize = _size;
if (_size + size >= _capacity) {
_capacity += MEM_STEPS;
auto newLoc = realloc(_out, _capacity * sizeof(uint8_t));
if (newLoc == nullptr) {
throw ArbUt::Exception("Out of memory.");
}
_out = (uint8_t*)newLoc;
}
auto start = reinterpret_cast<const uint8_t*>(ptr);
for (asUINT index = 0; index < size; index++) {
_out[initialSize + index] = *(start + index);
}
_size += size;
return size;
}
void WriteToPosition(const void* non_null ptr, asUINT size, size_t position) {
auto start = reinterpret_cast<const uint8_t*>(ptr);
for (asUINT index = 0; index < size; index++) {
_out[position + index] = *(start + index);
}
}
int Read(void* non_null ptr, asUINT size) final {
if (size == 0)
return 0;
auto toRead = size;
if (_index + toRead >= _size) {
toRead = _size - _index;
}
auto start = reinterpret_cast<uint8_t*>(ptr);
for (asUINT index = 0; index < toRead; index++) {
*(start + index) = _out[_index + index];
}
_index += toRead;
return toRead;
}
};
#undef MEM_STEPS
#endif // PKMNLIB_MEMORYBYTECODESTREAM_HPP