You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
2.1 KiB

#pragma once
#include <cerrno>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include "utils/endian_read.hpp"
#include "utils/endian_write.hpp"
#include "utils/log.hpp"
namespace devilution {
inline void LoggedFread(void *buffer, size_t size, FILE *stream)
{
if (std::fread(buffer, size, 1, stream) != 1 && !std::feof(stream)) {
LogError("fread failed: {}", std::strerror(errno));
}
}
inline void LoggedFwrite(const void *buffer, size_t size, FILE *stream)
{
if (std::fwrite(buffer, size, 1, stream) != 1) {
LogError("fwrite failed: {}", std::strerror(errno));
}
}
template <typename T = uint8_t>
T ReadByte(FILE *stream)
{
static_assert(sizeof(T) == 1, "invalid argument");
char buf;
LoggedFread(&buf, sizeof(buf), stream);
return static_cast<T>(buf);
}
template <typename T = uint16_t>
T ReadLE16(FILE *stream)
{
static_assert(sizeof(T) == 2, "invalid argument");
char buf[2];
LoggedFread(&buf, sizeof(buf), stream);
return static_cast<T>(LoadLE16(buf));
}
template <typename T = uint32_t>
T ReadLE32(FILE *stream)
{
static_assert(sizeof(T) == 4, "invalid argument");
char buf[4];
LoggedFread(&buf, sizeof(buf), stream);
return static_cast<T>(LoadLE32(buf));
}
inline float ReadLEFloat(FILE *stream)
{
static_assert(sizeof(float) == sizeof(uint32_t), "invalid float size");
const uint32_t val = ReadLE32(stream);
float result;
memcpy(&result, &val, sizeof(float));
return result;
}
inline void WriteByte(FILE *out, uint8_t val)
{
LoggedFwrite(&val, sizeof(val), out);
}
inline void WriteLE16(FILE *out, uint16_t val)
{
char data[2];
WriteLE16(data, val);
LoggedFwrite(data, sizeof(data), out);
}
inline void WriteLE32(FILE *out, uint32_t val)
{
char data[4];
WriteLE32(data, val);
LoggedFwrite(data, sizeof(data), out);
}
inline void WriteLEFloat(FILE *out, float val)
{
static_assert(sizeof(float) == sizeof(uint32_t), "invalid float size");
uint32_t intVal;
memcpy(&intVal, &val, sizeof(uint32_t));
char data[4];
WriteLE32(data, intVal);
LoggedFwrite(data, sizeof(data), out);
}
} // namespace devilution