#pragma once #ifndef __BINARYIO__H__ #define __BINARYIO__H__ #include #include #include #include "Game.h" #include "Logger.h" namespace BinaryIO { template std::ostream& BinaryWrite(std::ostream& stream, const T& value) { return stream.write(reinterpret_cast(&value), sizeof(T)); } template std::istream& BinaryRead(std::istream& stream, T& value) { if (!stream.good()) throw std::runtime_error("Failed to read from istream."); return stream.read(reinterpret_cast(&value), sizeof(T)); } enum class ReadType : int8_t { WideString = 0, String = 1, }; template inline void ReadString(std::istream& stream, std::u16string& value) { static_assert(std::is_integral::value, "SizeType must be an integral type."); SizeType size; BinaryRead(stream, size); if (!stream.good()) throw std::runtime_error("Failed to read from istream."); value.resize(size); stream.read(reinterpret_cast(value.data()), size * sizeof(uint16_t)); } template inline void ReadString(std::istream& stream, std::string& value, ReadType readType) { static_assert(std::is_integral::value, "SizeType must be an integral type."); SizeType size; BinaryRead(stream, size); if (!stream.good()) throw std::runtime_error("Failed to read from istream."); value.resize(size); if (readType == ReadType::WideString) { uint16_t wideChar; // Faster to do this than to read a u16string and convert it to a string since we only go through allocator once for (SizeType i = 0; i < size; ++i) { BinaryRead(stream, wideChar); value[i] = static_cast(wideChar); } } else { stream.read(value.data(), size); } } std::string ReadString(std::istream& instream); inline bool DoesFileExist(const std::string& name) { std::ifstream f(name.c_str()); return f.good(); } } #endif //!__BINARYIO__H__