MassBuilderSaveTool/src/UESaveFile/BinaryWriter.h

111 lines
3.9 KiB
C++

#pragma once
// MassBuilderSaveTool
// Copyright (C) 2021-2022 Guillaume Jacquemin
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <cstdio>
#include <Corrade/Containers/ArrayView.h>
#include <Corrade/Containers/GrowableArray.h>
#include <Corrade/Containers/StaticArray.h>
#include <Corrade/Utility/StlForwardString.h>
#include <Magnum/Types.h>
using namespace Corrade;
using namespace Magnum;
class BinaryWriter {
public:
explicit BinaryWriter(const std::string& filename);
~BinaryWriter();
BinaryWriter(const BinaryWriter& other) = delete;
BinaryWriter& operator=(const BinaryWriter& other) = delete;
BinaryWriter(BinaryWriter&& other) = default;
BinaryWriter& operator=(BinaryWriter&& other) = default;
auto open() -> bool;
void closeFile();
auto position() -> Long;
auto array() const -> Containers::ArrayView<const char>;
auto arrayPosition() const -> UnsignedLong;
auto flushToFile() -> bool;
auto writeByte(Byte value) -> bool;
auto writeChar(char value) -> bool;
auto writeUnsignedByte(UnsignedByte value) -> bool;
auto writeShort(Short value) -> bool;
auto writeUnsignedShort(UnsignedShort value) -> bool;
auto writeInt(Int value) -> bool;
auto writeUnsignedInt(UnsignedInt value) -> bool;
auto writeLong(Long value) -> bool;
auto writeUnsignedLong(UnsignedLong value) -> bool;
auto writeFloat(Float value) -> bool;
auto writeDouble(Double value) -> bool;
auto writeArray(Containers::ArrayView<const char> array) -> bool;
template<std::size_t size>
auto writeString(const char(&str)[size]) -> bool {
return writeArray({str, size - 1});
}
template<std::size_t S>
auto writeStaticArray(Containers::StaticArrayView<S, const char> array) -> bool {
return std::fwrite(array.data(), sizeof(char), S, _file) == S;
}
auto writeUEString(const std::string& str) -> bool;
template<typename T, typename U = std::conditional_t<std::is_trivially_copyable<T>::value, T, T&>>
auto writeValueToArray(U value) -> UnsignedLong {
Containers::ArrayView<T> view{&value, 1};
return writeDataToArray(view);
}
auto writeUEStringToArray(const std::string& value) -> UnsignedLong;
template<typename T>
void writeValueToArrayAt(T& value, UnsignedLong position) {
Containers::ArrayView<T> view{&value, 1};
writeDataToArrayAt(view, position);
}
template<typename T>
auto writeDataToArray(Containers::ArrayView<T> view) -> UnsignedLong {
arrayAppend(_data, Containers::arrayCast<const char>(view));
_index += sizeof(T) * view.size();
return sizeof(T) * view.size();
}
template<typename T>
void writeDataToArrayAt(Containers::ArrayView<T> view, UnsignedLong position) {
auto casted_view = Containers::arrayCast<const char>(view);
for(UnsignedLong i = 0; i < casted_view.size(); i++) {
_data[position + i] = casted_view[i];
}
}
private:
FILE* _file = nullptr;
Containers::Array<char> _data;
UnsignedLong _index = 0;
};