#ifndef PKMNLIB_MEMORYBYTECODESTREAM_HPP #define PKMNLIB_MEMORYBYTECODESTREAM_HPP #include #include 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(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(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(ptr); for (asUINT index = 0; index < toRead; index++) { *(start + index) = _out[_index + index]; } _index += toRead; return toRead; } }; #undef MEM_STEPS #endif // PKMNLIB_MEMORYBYTECODESTREAM_HPP