#pragma once #include #include #include namespace Pomme { class StreamPosGuard { std::istream& stream; const std::streampos backup; bool active; public: StreamPosGuard(std::istream& f); ~StreamPosGuard(); void Cancel(); }; class BigEndianIStream { public: BigEndianIStream(std::istream& theStream); void Read(char* dst, size_t n); void Skip(size_t n); void Goto(std::streamoff absoluteOffset); std::streampos Tell() const; StreamPosGuard GuardPos(); std::vector ReadBytes(size_t n); std::string ReadPascalString(); std::string ReadPascalString_FixedLengthRecord(const int maxChars); double Read80BitFloat(); template T Read() { char b[sizeof(T)]; Read(b, sizeof(T)); #if !(TARGET_RT_BIGENDIAN) if constexpr (sizeof(T) > 1) { std::reverse(b, b + sizeof(T)); } #endif return *(T*) b; } private: std::istream& stream; }; class BigEndianOStream { public: BigEndianOStream(std::ostream& theStream); void Write(const char* src, size_t n); void Goto(std::streamoff absoluteOffset); std::streampos Tell() const; void WritePascalString(const std::string& text, int padToAlignment = 1); void WriteRawString(const std::string& text); template void Write(T value) { char* b = (char*) &value; #if !(TARGET_RT_BIGENDIAN) if constexpr (sizeof(T) > 1) { std::reverse(b, b + sizeof(T)); } #endif Write(b, sizeof(T)); } private: std::ostream& stream; }; }