#ifndef OPENMW_COMPONENTS_BGSM_STREAM_HPP #define OPENMW_COMPONENTS_BGSM_STREAM_HPP #include #include #include #include #include #include #include #include #include #include #include #include namespace Bgsm { template inline void readBufferOfType(Files::IStreamPtr& pIStream, T* dest) { static_assert(std::is_arithmetic_v, "Buffer element type is not arithmetic"); pIStream->read(reinterpret_cast(dest), numInstances * sizeof(T)); if (pIStream->bad()) throw std::runtime_error("Failed to read typed (" + std::string(typeid(T).name()) + ") buffer of " + std::to_string(numInstances) + " instances"); if constexpr (Misc::IS_BIG_ENDIAN) for (std::size_t i = 0; i < numInstances; i++) Misc::swapEndiannessInplace(dest[i]); } template inline void readBufferOfType(Files::IStreamPtr& pIStream, T (&dest)[numInstances]) { readBufferOfType(pIStream, static_cast(dest)); } class BGSMStream { Files::IStreamPtr mStream; public: explicit BGSMStream(Files::IStreamPtr&& stream) : mStream(std::move(stream)) { } void skip(size_t size) { mStream->ignore(size); } /// Read into a single instance of type template void read(T& data) { readBufferOfType<1>(mStream, &data); } /// Read multiple instances of type into an array template void readArray(std::array& arr) { readBufferOfType(mStream, arr.data()); } }; template <> void BGSMStream::read(osg::Vec2f& vec); template <> void BGSMStream::read(osg::Vec3f& vec); template <> void BGSMStream::read(osg::Vec4f& vec); template <> void BGSMStream::read(std::string& str); } #endif