MassBuilderSaveTool/src/Gvas/BinaryWriter.h

113 lines
3.8 KiB
C++

#pragma once
// MassBuilderSaveTool
// Copyright (C) 2021-2023 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 <cstdint>
#include <cstdio>
#include <Corrade/Containers/ArrayView.h>
#include <Corrade/Containers/GrowableArray.h>
#include <Corrade/Containers/StaticArray.h>
#include <Corrade/Containers/StringView.h>
using namespace Corrade;
namespace Gvas {
class BinaryWriter {
public:
explicit BinaryWriter(Containers::StringView filename);
~BinaryWriter();
BinaryWriter(const BinaryWriter& other) = delete;
BinaryWriter& operator=(const BinaryWriter& other) = delete;
BinaryWriter(BinaryWriter&& other) = default;
BinaryWriter& operator=(BinaryWriter&& other) = default;
bool open();
void closeFile();
auto position() -> std::int64_t;
auto array() const -> Containers::ArrayView<const char>;
auto arrayPosition() const -> std::size_t;
bool flushToFile();
bool writeChar(char value);
bool writeInt8(std::int8_t value);
bool writeUint8(std::uint8_t value);
bool writeInt16(std::int16_t value);
bool writeUint16(std::uint16_t value);
bool writeInt32(std::int32_t value);
bool writeUint32(std::uint32_t value);
bool writeInt64(std::int64_t value);
bool writeUint64(std::uint64_t value);
bool writeFloat(float value);
bool writeDouble(double value);
bool writeArray(Containers::ArrayView<const char> array);
template<std::size_t size>
bool writeString(const char(&str)[size]) {
return writeArray({str, size - 1});
}
template<std::size_t S>
bool writeStaticArray(Containers::StaticArrayView<S, const char> array) {
return std::fwrite(array.data(), sizeof(char), S, _file) == S;
}
bool writeUEString(Containers::StringView str);
template<typename T, typename U = std::conditional_t<std::is_trivially_copyable<T>::value, T, T&>>
auto writeValueToArray(U value) -> std::size_t {
Containers::ArrayView<T> view{&value, 1};
return writeDataToArray(view);
}
auto writeUEStringToArray(Containers::StringView value) -> std::size_t;
template<typename T>
void writeValueToArrayAt(T& value, std::size_t position) {
Containers::ArrayView<T> view{&value, 1};
writeDataToArrayAt(view, position);
}
template<typename T>
auto writeDataToArray(Containers::ArrayView<T> view) -> std::size_t {
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, std::size_t position) {
auto casted_view = Containers::arrayCast<const char>(view);
for(std::size_t i = 0; i < casted_view.size(); i++) {
_data[position + i] = casted_view[i];
}
}
private:
FILE* _file = nullptr;
Containers::Array<char> _data;
std::size_t _index = 0;
};
}