164 lines
3.8 KiB
C++
164 lines
3.8 KiB
C++
// MassBuilderSaveTool
|
|
// Copyright (C) 2021-2024 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 "Writer.h"
|
|
|
|
using namespace Containers::Literals;
|
|
|
|
namespace BinaryIo {
|
|
|
|
Writer::Writer(Containers::StringView filename) {
|
|
_file = std::fopen(filename.data(), "wb");
|
|
if(!_file) {
|
|
LOG_ERROR_FORMAT("Couldn't open {} for reading: {}", filename, std::strerror(errno));
|
|
}
|
|
}
|
|
|
|
Writer::~Writer() {
|
|
closeFile();
|
|
}
|
|
|
|
bool
|
|
Writer::open() {
|
|
return _file;
|
|
}
|
|
|
|
void
|
|
Writer::closeFile() {
|
|
std::fflush(_file);
|
|
std::fclose(_file);
|
|
_file = nullptr;
|
|
}
|
|
|
|
std::int64_t
|
|
Writer::position() {
|
|
return _ftelli64(_file);
|
|
}
|
|
|
|
Containers::ArrayView<const char>
|
|
Writer::array() const {
|
|
return _data;
|
|
}
|
|
|
|
std::size_t
|
|
Writer::arrayPosition() const {
|
|
return _index;
|
|
}
|
|
|
|
bool
|
|
Writer::flushToFile() {
|
|
bool ret = writeArray(_data);
|
|
std::fflush(_file);
|
|
_data = Containers::Array<char>{};
|
|
_index = 0;
|
|
return ret;
|
|
}
|
|
|
|
bool
|
|
Writer::writeChar(char value) {
|
|
return std::fwrite(&value, sizeof(char), 1, _file) == 1;
|
|
}
|
|
|
|
bool
|
|
Writer::writeInt8(std::int8_t value) {
|
|
return std::fwrite(&value, sizeof(std::int8_t), 1, _file) == 1;
|
|
}
|
|
|
|
bool
|
|
Writer::writeUint8(std::uint8_t value) {
|
|
return std::fwrite(&value, sizeof(std::uint8_t), 1, _file) == 1;
|
|
}
|
|
|
|
bool
|
|
Writer::writeInt16(std::int16_t value) {
|
|
return std::fwrite(&value, sizeof(std::int16_t), 1, _file) == 1;
|
|
}
|
|
|
|
bool
|
|
Writer::writeUint16(std::uint16_t value) {
|
|
return std::fwrite(&value, sizeof(std::uint16_t), 1, _file) == 1;
|
|
}
|
|
|
|
bool
|
|
Writer::writeInt32(std::int32_t value) {
|
|
return std::fwrite(&value, sizeof(std::int32_t), 1, _file) == 1;
|
|
}
|
|
|
|
bool
|
|
Writer::writeUint32(std::uint32_t value) {
|
|
return std::fwrite(&value, sizeof(std::uint32_t), 1, _file) == 1;
|
|
}
|
|
|
|
bool
|
|
Writer::writeInt64(std::int64_t value) {
|
|
return std::fwrite(&value, sizeof(std::int64_t), 1, _file) == 1;
|
|
}
|
|
|
|
bool
|
|
Writer::writeUint64(std::uint64_t value) {
|
|
return std::fwrite(&value, sizeof(std::uint64_t), 1, _file) == 1;
|
|
}
|
|
|
|
bool
|
|
Writer::writeFloat(float value) {
|
|
return std::fwrite(&value, sizeof(float), 1, _file) == 1;
|
|
}
|
|
|
|
bool
|
|
Writer::writeDouble(double value) {
|
|
return std::fwrite(&value, sizeof(double), 1, _file) == 1;
|
|
}
|
|
|
|
bool
|
|
Writer::writeArray(Containers::ArrayView<const char> array) {
|
|
if(array.isEmpty()) {
|
|
return false;
|
|
}
|
|
|
|
return std::fwrite(array.data(), sizeof(char), array.size(), _file) == array.size();
|
|
}
|
|
|
|
bool
|
|
Writer::writeUEString(Containers::StringView str) {
|
|
if(str.size() > UINT32_MAX) {
|
|
LOG_ERROR_FORMAT("String is too big. Expected size() < UINT32_MAX, got {} instead.", str.size());
|
|
return false;
|
|
}
|
|
|
|
writeUint32(static_cast<std::uint32_t>(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');
|
|
}
|
|
|
|
std::size_t
|
|
Writer::writeUEStringToArray(Containers::StringView value) {
|
|
return writeValueToArray<std::uint32_t>(std::uint32_t(value.size()) + 1u) +
|
|
writeDataToArray(Containers::ArrayView<const char>{value}) +
|
|
writeValueToArray<char>('\0');
|
|
}
|
|
|
|
}
|