mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2024-12-28 00:15:06 +00:00
78 lines
2.2 KiB
C++
78 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
|