OpenMW
components/nif/nifstream.hpp
Go to the documentation of this file.
00001 #ifndef OPENMW_COMPONENTS_NIF_NIFSTREAM_HPP
00002 #define OPENMW_COMPONENTS_NIF_NIFSTREAM_HPP
00003 
00004 namespace Nif
00005 {
00006 
00007 class NIFFile;
00008 
00009 class NIFStream {
00010 
00012     Ogre::DataStreamPtr inp;
00013 
00014     uint8_t read_byte()
00015     {
00016         uint8_t byte;
00017         if(inp->read(&byte, 1) != 1) return 0;
00018         return byte;
00019     }
00020     uint16_t read_le16()
00021     {
00022         uint8_t buffer[2];
00023         if(inp->read(buffer, 2) != 2) return 0;
00024         return buffer[0] | (buffer[1]<<8);
00025     }
00026     uint32_t read_le32()
00027     {
00028         uint8_t buffer[4];
00029         if(inp->read(buffer, 4) != 4) return 0;
00030         return buffer[0] | (buffer[1]<<8) | (buffer[2]<<16) | (buffer[3]<<24);
00031     }
00032     float read_le32f()
00033     {
00034         union {
00035             uint32_t i;
00036             float f;
00037         } u = { read_le32() };
00038         return u.f;
00039     }
00040 
00041 public:
00042 
00043     NIFFile * const file;
00044 
00045     NIFStream (NIFFile * file, Ogre::DataStreamPtr inp): file (file), inp (inp) {}
00046 
00047     /*************************************************
00048                Parser functions
00049     ****************************************************/
00050 
00051     template <typename T>
00052     struct GetHandler
00053     {
00054         typedef T (NIFStream::*fn_t)();
00055 
00056         static const fn_t sValue; // this is specialized per supported type in the .cpp file
00057 
00058         static T read (NIFStream* nif)
00059         {
00060             return (nif->*sValue) ();
00061         }
00062     };
00063 
00064     template <typename T>
00065     void read (NIFStream* nif, T & Value)
00066     {
00067         Value = GetHandler <T>::read (nif);
00068     }
00069 
00070     void skip(size_t size) { inp->skip(size); }
00071     void read (void * data, size_t size) { inp->read (data, size); }
00072 
00073     char getChar() { return read_byte(); }
00074     short getShort() { return read_le16(); }
00075     unsigned short getUShort() { return read_le16(); }
00076     int getInt() { return read_le32(); }
00077     int getUInt() { return read_le32(); }
00078     float getFloat() { return read_le32f(); }
00079     Ogre::Vector2 getVector2()
00080     {
00081         float a[2];
00082         for(size_t i = 0;i < 2;i++)
00083             a[i] = getFloat();
00084         return Ogre::Vector2(a);
00085     }
00086     Ogre::Vector3 getVector3()
00087     {
00088         float a[3];
00089         for(size_t i = 0;i < 3;i++)
00090             a[i] = getFloat();
00091         return Ogre::Vector3(a);
00092     }
00093     Ogre::Vector4 getVector4()
00094     {
00095         float a[4];
00096         for(size_t i = 0;i < 4;i++)
00097             a[i] = getFloat();
00098         return Ogre::Vector4(a);
00099     }
00100     Ogre::Matrix3 getMatrix3()
00101     {
00102         Ogre::Real a[3][3];
00103         for(size_t i = 0;i < 3;i++)
00104         {
00105             for(size_t j = 0;j < 3;j++)
00106                 a[i][j] = Ogre::Real(getFloat());
00107         }
00108         return Ogre::Matrix3(a);
00109     }
00110     Ogre::Quaternion getQuaternion()
00111     {
00112         float a[4];
00113         for(size_t i = 0;i < 4;i++)
00114             a[i] = getFloat();
00115         return Ogre::Quaternion(a);
00116     }
00117     Transformation getTrafo()
00118     {
00119         Transformation t;
00120         t.pos = getVector3();
00121         t.rotation = getMatrix3();
00122         t.scale = getFloat();
00123         return t;
00124     }
00125 
00126     std::string getString(size_t length)
00127     {
00128         std::vector<char> str (length+1, 0);
00129 
00130         if(inp->read(&str[0], length) != length)
00131             throw std::runtime_error ("string length in NIF file does not match");
00132 
00133         return &str[0];
00134     }
00135     std::string getString()
00136     {
00137         size_t size = read_le32();
00138         return getString(size);
00139     }
00140 
00141     void getShorts(std::vector<short> &vec, size_t size)
00142     {
00143         vec.resize(size);
00144         for(size_t i = 0;i < vec.size();i++)
00145             vec[i] = getShort();
00146     }
00147     void getFloats(std::vector<float> &vec, size_t size)
00148     {
00149         vec.resize(size);
00150         for(size_t i = 0;i < vec.size();i++)
00151             vec[i] = getFloat();
00152     }
00153     void getVector2s(std::vector<Ogre::Vector2> &vec, size_t size)
00154     {
00155         vec.resize(size);
00156         for(size_t i = 0;i < vec.size();i++)
00157             vec[i] = getVector2();
00158     }
00159     void getVector3s(std::vector<Ogre::Vector3> &vec, size_t size)
00160     {
00161         vec.resize(size);
00162         for(size_t i = 0;i < vec.size();i++)
00163             vec[i] = getVector3();
00164     }
00165     void getVector4s(std::vector<Ogre::Vector4> &vec, size_t size)
00166     {
00167         vec.resize(size);
00168         for(size_t i = 0;i < vec.size();i++)
00169             vec[i] = getVector4();
00170     }
00171     void getQuaternions(std::vector<Ogre::Quaternion> &quat, size_t size)
00172     {
00173         quat.resize(size);
00174         for(size_t i = 0;i < quat.size();i++)
00175             quat[i] = getQuaternion();
00176     }
00177 };
00178 
00179 }
00180 
00181 #endif