From de3c76a54bd47798162838ff97cf66a4595baefa Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 30 Apr 2013 14:53:41 +0200 Subject: [PATCH] Revert "reworked NIFStream to use a type-handler" This reverts commit 03ee7663a3e89698c36108d03a7fcd036762d827. --- components/nif/nifstream.hpp | 338 ++++++++++++----------------------- 1 file changed, 113 insertions(+), 225 deletions(-) diff --git a/components/nif/nifstream.hpp b/components/nif/nifstream.hpp index 7abfae9e8..a2595d17b 100644 --- a/components/nif/nifstream.hpp +++ b/components/nif/nifstream.hpp @@ -1,8 +1,6 @@ #ifndef OPENMW_COMPONENTS_NIF_NIFSTREAM_HPP #define OPENMW_COMPONENTS_NIF_NIFSTREAM_HPP -#include - namespace Nif { @@ -13,278 +11,168 @@ class NIFStream { /// Input stream Ogre::DataStreamPtr inp; - template - value_t read_le () + uint8_t read_byte() { - uint8_t buffer [sizeof (value_t)]; - - if (inp->read (buffer, sizeof (buffer)) != sizeof (buffer)) - throw std::runtime_error ("unexpected"); - - value_t Value = 0; - value_t Shift = 0; - - for (size_t i = 0; i < sizeof (value_t); ++i) - { - Value |= value_t (buffer[i]) << Shift; - Shift += 8; - } - - return Value; + uint8_t byte; + if(inp->read(&byte, 1) != 1) return 0; + return byte; + } + uint16_t read_le16() + { + uint8_t buffer[2]; + if(inp->read(buffer, 2) != 2) return 0; + return buffer[0] | (buffer[1]<<8); + } + uint32_t read_le32() + { + uint8_t buffer[4]; + if(inp->read(buffer, 4) != 4) return 0; + return buffer[0] | (buffer[1]<<8) | (buffer[2]<<16) | (buffer[3]<<24); + } + float read_le32f() + { + union { + uint32_t i; + float f; + } u = { read_le32() }; + return u.f; } public: - /* - * This should be true for any processor/platform whose endianess, alignment - * and packing rules would be compatible with x86 and not fault or degrade - * with misaligned reads. This enables some pretty big savings when reading in - * animations and meshes. - */ -#if defined (__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) - static const bool FileCompatiblePlatform = true; -#else - static const bool FileCompatiblePlatform = false; -#endif - - template - struct handler; - - template - struct le_handler; - - template - friend struct le_handler; - - template - struct conversion_handler; - NIFFile * const file; - NIFStream (NIFFile * file, Ogre::DataStreamPtr inp) : file (file), inp (inp) {} + NIFStream (NIFFile * file, Ogre::DataStreamPtr inp): file (file), inp (inp) {} /************************************************* Parser functions ****************************************************/ - void skip(size_t size) { return inp->skip (size); } - size_t read (void * data, size_t size) { return inp->read (data, size); } + template + struct GetHandler + { + typedef T (NIFStream::*fn_t)(); + + static const fn_t sValue; // this is specialized per supported type in the .cpp file + + static T read (NIFStream* nif) + { + return (nif->*sValue) (); + } + }; template - void uncheckedRead (T & Value) + void read (NIFStream* nif, T & Value) { - typedef handler handler_t; - handler_t::extract (*this, Value); + Value = GetHandler ::read (nif); } - template - T getValue () - { - T Value; - getValue (Value); - return Value; - } + void skip(size_t size) { inp->skip(size); } + void read (void * data, size_t size) { inp->read (data, size); } - template - void getValue (T & Value) + char getChar() { return read_byte(); } + short getShort() { return read_le16(); } + unsigned short getUShort() { return read_le16(); } + int getInt() { return read_le32(); } + int getUInt() { return read_le32(); } + float getFloat() { return read_le32f(); } + Ogre::Vector2 getVector2() { - typedef handler handler_t; - if (FileCompatiblePlatform && handler_t::FileCompatibleLayout) + float a[2]; + for(size_t i = 0;i < 2;i++) + a[i] = getFloat(); + return Ogre::Vector2(a); + } + Ogre::Vector3 getVector3() + { + float a[3]; + for(size_t i = 0;i < 3;i++) + a[i] = getFloat(); + return Ogre::Vector3(a); + } + Ogre::Vector4 getVector4() + { + float a[4]; + for(size_t i = 0;i < 4;i++) + a[i] = getFloat(); + return Ogre::Vector4(a); + } + Ogre::Matrix3 getMatrix3() + { + Ogre::Real a[3][3]; + for(size_t i = 0;i < 3;i++) { - BOOST_STATIC_ASSERT_MSG (handler_t::FixedLength, "non-fixed length encoding not supported..."); - BOOST_STATIC_ASSERT_MSG (handler_t::EncodedLength == sizeof (T), "unexpected structure size"); - - inp->read (&Value, handler_t::EncodedLength); - } - else - { - handler_t::extract (*this, Value); + for(size_t j = 0;j < 3;j++) + a[i][j] = Ogre::Real(getFloat()); } + return Ogre::Matrix3(a); } - - template - void getArray (element_type * Array, size_t Size) + Ogre::Quaternion getQuaternion() { - typedef handler handler_t; - - if (FileCompatiblePlatform && handler_t::FileCompatibleLayout) - { - BOOST_STATIC_ASSERT_MSG (handler_t::FixedLength, "non-fixed length encoding not supported..."); - BOOST_STATIC_ASSERT_MSG (handler_t::EncodedLength == sizeof (element_type), "unexpected structure size"); - - inp->read (Array, handler_t::EncodedLength * Size); - } - else - { - for(size_t i = 0; i < Size; i++) - handler_t::extract (*this, Array[i]); - } + float a[4]; + for(size_t i = 0;i < 4;i++) + a[i] = getFloat(); + return Ogre::Quaternion(a); } - - template - void getStdVector (std::vector & Vector, size_t Size) + Transformation getTrafo() { - Vector.resize(Size); - - getArray (&Vector.front (), Vector.size ()); + Transformation t; + t.pos = getVector3(); + t.rotation = getMatrix3(); + t.scale = getFloat(); + return t; } - template - void getStdVector (std::vector & Vector) - { - length_type Length; - - getValue (Length); - - getStdVector (Vector, Length); - } - - char getChar() { return getValue (); } - signed int getInt() { return getValue (); } - unsigned int getUInt() { return getValue (); } - signed short getShort() { return getValue (); } - unsigned short getUShort() { return getValue (); } - //signed long getLong() { return getValue (); } - //unsigned long getULong() { return getValue (); } - float getFloat() { return getValue (); } - - Ogre::Vector2 getVector2() { return getValue (); } - Ogre::Vector3 getVector3() { return getValue (); } - Ogre::Vector4 getVector4() { return getValue (); } - Ogre::Matrix3 getMatrix3() { return getValue (); } - Ogre::Quaternion getQuaternion() { return getValue (); } - - Transformation getTrafo() { return getValue (); } - - void getShorts(std::vector &vec, size_t size) { return getStdVector (vec, size); } - void getFloats(std::vector &vec, size_t size) { return getStdVector (vec, size); } - void getVector2s(std::vector &vec, size_t size) { return getStdVector (vec, size); } - void getVector3s(std::vector &vec, size_t size) { return getStdVector (vec, size); } - void getVector4s(std::vector &vec, size_t size) { return getStdVector (vec, size); } - void getQuaternions(std::vector &vec, size_t size) { return getStdVector (vec, size); } - std::string getString(size_t length) { std::vector str (length+1, 0); - if(read(&str[0], length) != length) + if(inp->read(&str[0], length) != length) throw std::runtime_error ("string length in NIF file does not match"); return &str[0]; } std::string getString() { - size_t size = getValue (); + size_t size = read_le32(); return getString(size); } -}; -/* - * generic type handlers - */ - -template -struct NIFStream::handler < type [Size] > -{ - typedef handler inner_handler; - - static const bool FixedLength = inner_handler::FixedLength; - static const size_t EncodedLength = inner_handler::EncodedLength * Size; - static const bool FileCompatibleLayout = inner_handler::FileCompatibleLayout; - - static void extract (NIFStream & Stream, type (&Value) [Size]) + void getShorts(std::vector &vec, size_t size) { - for (size_t i = 0; i < Size; ++i) - inner_handler::extract (Stream, Value [i]); + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getShort(); } -}; - -template -struct NIFStream::le_handler -{ - static const bool FixedLength = true; - static const size_t EncodedLength = sizeof (backing_type); - static const bool FileCompatibleLayout = true; - - static void extract (NIFStream & Stream, presentation_type & Value) + void getFloats(std::vector &vec, size_t size) { - BOOST_STATIC_ASSERT_MSG(sizeof (presentation_type) == sizeof (backing_type), "Invalid use of NIFile::le_handler template"); - - union { - - backing_type Backing; - presentation_type Presentation; - - } u; - - u.Backing = Stream.read_le (); - - Value = u.Presentation; + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getFloat(); } -}; - -template -struct NIFStream::conversion_handler -{ - typedef handler store_handler; - - static const bool FixedLength = store_handler::FixedLength; - static const size_t EncodedLength = store_handler::EncodedLength; - static const bool FileCompatibleLayout = false; - - static void extract (NIFStream & Stream, final_type & Value) + void getVector2s(std::vector &vec, size_t size) { - store_type StoreValue; - store_handler::extract (Stream, StoreValue); - Value = final_type (StoreValue); + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getVector2(); } -}; - -template -struct NIFStream::conversion_handler -{ - typedef handler store_handler; - - static const bool FixedLength = store_handler::FixedLength; - static const size_t EncodedLength = store_handler::EncodedLength; - static const bool FileCompatibleLayout = store_handler::FileCompatibleLayout; - - static void extract (NIFStream & Stream, final_type & FinalValue) + void getVector3s(std::vector &vec, size_t size) { - store_handler::extract (Stream, reinterpret_cast (FinalValue)); + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getVector3(); } -}; - -template <> struct NIFStream::handler : NIFStream::le_handler {}; -template <> struct NIFStream::handler : NIFStream::le_handler {}; -template <> struct NIFStream::handler : NIFStream::le_handler {}; -template <> struct NIFStream::handler : NIFStream::le_handler {}; -template <> struct NIFStream::handler : NIFStream::le_handler {}; -template <> struct NIFStream::handler : NIFStream::le_handler {}; - -template <> struct NIFStream::handler : NIFStream::le_handler {}; -template <> struct NIFStream::handler : NIFStream::le_handler {}; - -template <> struct NIFStream::handler : NIFStream::conversion_handler {}; -template <> struct NIFStream::handler : NIFStream::conversion_handler {}; -template <> struct NIFStream::handler : NIFStream::conversion_handler {}; -template <> struct NIFStream::handler : NIFStream::conversion_handler {}; -template <> struct NIFStream::handler : NIFStream::conversion_handler {}; - -template <> struct NIFStream::handler -{ - static const bool FixedLength = true; - static const size_t EncodedLength = - handler ::EncodedLength + - handler ::EncodedLength + - handler ::EncodedLength; - static const bool FileCompatibleLayout = true; - - static void extract (NIFStream & stream, Transformation & value) + void getVector4s(std::vector &vec, size_t size) { - stream.uncheckedRead (value.pos); - stream.uncheckedRead (value.rotation); - stream.uncheckedRead (value.scale); + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getVector4(); + } + void getQuaternions(std::vector &quat, size_t size) + { + quat.resize(size); + for(size_t i = 0;i < quat.size();i++) + quat[i] = getQuaternion(); } };