MassBuilderSaveTool/src/UESaveFile/BinaryWriter.cpp

140 lines
4.0 KiB
C++

// 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 <cstring>
#include "../Logger/Logger.h"
#include "BinaryWriter.h"
using namespace Containers::Literals;
BinaryWriter::BinaryWriter(Containers::StringView filename) {
_file = std::fopen(filename.data(), "wb");
if(!_file) {
LOG_ERROR_FORMAT("Couldn't open {} for reading: {}", filename, std::strerror(errno));
}
}
BinaryWriter::~BinaryWriter() {
closeFile();
}
auto BinaryWriter::open() -> bool {
return _file;
}
void BinaryWriter::closeFile() {
std::fflush(_file);
std::fclose(_file);
_file = nullptr;
}
auto BinaryWriter::position() -> Long {
return _ftelli64(_file);
}
auto BinaryWriter::array() const -> Containers::ArrayView<const char> {
return _data;
}
auto BinaryWriter::arrayPosition() const -> UnsignedLong {
return _index;
}
auto BinaryWriter::flushToFile() -> bool {
bool ret = writeArray(_data);
std::fflush(_file);
_data = Containers::Array<char>{};
_index = 0;
return ret;
}
auto BinaryWriter::writeChar(char value) -> bool {
return std::fwrite(&value, sizeof(char), 1, _file) == 1;
}
auto BinaryWriter::writeByte(Byte value) -> bool {
return std::fwrite(&value, sizeof(Byte), 1, _file) == 1;
}
auto BinaryWriter::writeUnsignedByte(UnsignedByte value) -> bool {
return std::fwrite(&value, sizeof(UnsignedByte), 1, _file) == 1;
}
auto BinaryWriter::writeShort(Short value) -> bool {
return std::fwrite(&value, sizeof(Short), 1, _file) == 1;
}
auto BinaryWriter::writeUnsignedShort(UnsignedShort value) -> bool {
return std::fwrite(&value, sizeof(UnsignedShort), 1, _file) == 1;
}
auto BinaryWriter::writeInt(Int value) -> bool {
return std::fwrite(&value, sizeof(Int), 1, _file) == 1;
}
auto BinaryWriter::writeUnsignedInt(UnsignedInt value) -> bool {
return std::fwrite(&value, sizeof(UnsignedInt), 1, _file) == 1;
}
auto BinaryWriter::writeLong(Long value) -> bool {
return std::fwrite(&value, sizeof(Long), 1, _file) == 1;
}
auto BinaryWriter::writeUnsignedLong(UnsignedLong value) -> bool {
return std::fwrite(&value, sizeof(UnsignedLong), 1, _file) == 1;
}
auto BinaryWriter::writeFloat(Float value) -> bool {
return std::fwrite(&value, sizeof(Float), 1, _file) == 1;
}
auto BinaryWriter::writeDouble(Double value) -> bool {
return std::fwrite(&value, sizeof(Double), 1, _file) == 1;
}
auto BinaryWriter::writeArray(Containers::ArrayView<const char> array) -> bool {
if(array.size() == 0) {
return false;
}
return std::fwrite(array.data(), sizeof(char), array.size(), _file) == array.size();
}
auto BinaryWriter::writeUEString(Containers::StringView str) -> bool {
if(str.size() > UINT32_MAX) {
LOG_ERROR_FORMAT("String is too big. Expected size() < UINT32_MAX, got {} instead.", str.size());
return false;
}
writeUnsignedInt(static_cast<UnsignedInt>(str.size()) + 1);
if(str.size() > 0) {
std::size_t count = std::fwrite(str.data(), sizeof(char), str.size(), _file);
if(count != str.size()) {
return false;
}
}
return writeChar('\0');
}
auto BinaryWriter::writeUEStringToArray(Containers::StringView value) -> UnsignedLong {
return writeValueToArray<UnsignedInt>(UnsignedInt(value.size()) + 1u) +
writeDataToArray(Containers::ArrayView<const char>{value}) +
writeValueToArray<char>('\0');
}