#include "ByteArray.hpp"

#include <cstring>

namespace spider {

    ByteArray::ByteArray(isize length) : _mem(nullptr), _size(length) {
        if (_size > 0) {
            _mem = new u8[_size];
            std::memset(_mem, 0, _size);
        }
    }

    ByteArray::ByteArray(const ByteArray& other) : _mem(new u8[other._size]), _size(other._size) {
        std::copy(other._mem, other._mem + _size, _mem);
    }

    ByteArray::ByteArray(ByteArray&& other) noexcept : _mem(other._mem), _size(other._size) {
        other._mem = nullptr;
        other._size = 0;
    }

    ByteArray::~ByteArray() {
        delete[] _mem;
    }

    ByteArray& ByteArray::operator=(const ByteArray& other) {
        if (this == &other) return *this; // lock self

        u8* new_mem = new u8[other._size];
        std::copy(other._mem, other._mem + other._size, new_mem);

        delete[] _mem;
        _mem = new_mem;
        _size = other._size;

        return *this;
    }

    ByteArray& ByteArray::operator=(ByteArray&& other) noexcept {
        if (this == &other) return *this; // lock self

        delete[] _mem;

        _mem = other._mem; // time to steal!
        _size = other._size;

        other._mem = nullptr; // leave as a husk
        other._size = 0;

        return *this;
    }

    u8& ByteArray::operator[](isize index) {
        return _mem[index];
    }

    u8 ByteArray::operator[](isize index) const {
        return _mem[index];
    }

    u8* ByteArray::data() {
        return _mem;
    }

    const u8* ByteArray::data() const {
        return _mem;
    }

    isize ByteArray::size() const {
        return _size;
    }

}
