mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 04:56:39 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			77 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
	
		
			2.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#ifndef OPENMW_COMPONENTS_BGSM_STREAM_HPP
 | 
						|
#define OPENMW_COMPONENTS_BGSM_STREAM_HPP
 | 
						|
 | 
						|
#include <array>
 | 
						|
#include <cassert>
 | 
						|
#include <cstdint>
 | 
						|
#include <istream>
 | 
						|
#include <stdexcept>
 | 
						|
#include <string>
 | 
						|
#include <type_traits>
 | 
						|
 | 
						|
#include <components/files/istreamptr.hpp>
 | 
						|
#include <components/misc/endianness.hpp>
 | 
						|
 | 
						|
#include <osg/Vec2f>
 | 
						|
#include <osg/Vec3f>
 | 
						|
#include <osg/Vec4f>
 | 
						|
 | 
						|
namespace Bgsm
 | 
						|
{
 | 
						|
    template <std::size_t numInstances, typename T>
 | 
						|
    inline void readBufferOfType(Files::IStreamPtr& pIStream, T* dest)
 | 
						|
    {
 | 
						|
        static_assert(std::is_arithmetic_v<T>, "Buffer element type is not arithmetic");
 | 
						|
        pIStream->read(reinterpret_cast<char*>(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 <std::size_t numInstances, typename T>
 | 
						|
    inline void readBufferOfType(Files::IStreamPtr& pIStream, T (&dest)[numInstances])
 | 
						|
    {
 | 
						|
        readBufferOfType<numInstances>(pIStream, static_cast<T*>(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 <class T>
 | 
						|
        void read(T& data)
 | 
						|
        {
 | 
						|
            readBufferOfType<1>(mStream, &data);
 | 
						|
        }
 | 
						|
 | 
						|
        /// Read multiple instances of type into an array
 | 
						|
        template <class T, size_t size>
 | 
						|
        void readArray(std::array<T, size>& arr)
 | 
						|
        {
 | 
						|
            readBufferOfType<size>(mStream, arr.data());
 | 
						|
        }
 | 
						|
    };
 | 
						|
 | 
						|
    template <>
 | 
						|
    void BGSMStream::read<osg::Vec2f>(osg::Vec2f& vec);
 | 
						|
    template <>
 | 
						|
    void BGSMStream::read<osg::Vec3f>(osg::Vec3f& vec);
 | 
						|
    template <>
 | 
						|
    void BGSMStream::read<osg::Vec4f>(osg::Vec4f& vec);
 | 
						|
    template <>
 | 
						|
    void BGSMStream::read<std::string>(std::string& str);
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |