#pragma once
#include <array>
#include <cstring>
#include <istream>
#include <memory>
#include <string>
#include <vector>
#include <whiteout/common_types.h>
#include "concepts.h"
namespace whiteout {
namespace common {
class BinaryReader {
public:
BinaryReader(std::istream& inputStream) : file(inputStream) {
file.seekg(0, std::ios::end);
fileSize = static_cast<u32>(file.tellg());
file.seekg(0, std::ios::beg);
}
explicit BinaryReader(std::streambuf& buf)
: ownedStream_(std::make_unique<std::istream>(&buf)), file(*ownedStream_) {
file.seekg(0, std::ios::end);
fileSize = static_cast<u32>(file.tellg());
file.seekg(0, std::ios::beg);
}
~BinaryReader() {
}
template <BinaryBlob T>
T read() {
T value;
file.read(reinterpret_cast<char*>(&value), sizeof(T));
return value;
}
template <TrivialContiguousRange C>
C read(std::size_t count) {
C container(count); file.read(reinterpret_cast<char*>(std::data(container)),
std::size(container) * sizeof(typename C::value_type));
return container;
}
template <typename T, std::size_t N>
std::array<T, N> readArray() {
std::array<T, N> arr;
file.read(reinterpret_cast<char*>(arr.data()), sizeof(arr));
return arr;
}
void readBytes(char* buffer, u32 count) {
file.read(buffer, count);
}
std::string readString(std::size_t size, bool trimNulls = true) {
std::string str(size, '\0');
file.read(str.data(), size);
if (trimNulls) {
auto nullPos = str.find('\0');
if (nullPos != std::string::npos)
str.resize(nullPos);
}
return str;
}
std::string readZString() {
std::string result;
char c;
while (file.get(c) && c != '\0') {
result += c;
}
return result;
}
u32 getPosition() const {
return static_cast<u32>(file.tellg());
}
void setPosition(u32 pos) {
file.seekg(pos, std::ios::beg);
}
void skip(u32 count) {
file.seekg(count, std::ios::cur);
}
bool hasRemaining() {
return file.tellg() < fileSize;
}
u32 getRemainingBytes() {
u32 current = static_cast<u32>(file.tellg());
return fileSize - current;
}
bool isValid() const {
return file.good();
}
private:
std::unique_ptr<std::istream> ownedStream_;
std::istream& file;
u32 fileSize = 0;
};
} }