/* OpenMW - The completely unofficial reimplementation of Morrowind Copyright (C) 2008-2010 Nicolay Korslund Email: < korslund@gmail.com > WWW: http://openmw.sourceforge.net/ This file (nif_file.h) is part of the OpenMW package. OpenMW is distributed as free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License version 3 along with this program. If not, see http://www.gnu.org/licenses/ . */ #ifndef _NIF_FILE_H_ #define _NIF_FILE_H_ #include #include "../mangle/stream/stream.h" #include "../mangle/stream/filters/buffer_stream.h" #include "../mangle/tools/str_exception.h" #include "../tools/stringops.h" #include // Only used during development. Remove later. #include using namespace std; using namespace Mangle::Stream; // A simple array implementation containing a pointer and a // length. Used for holding slices into a data buffer. #include template struct SliceArray { const T* ptr; size_t length; SliceArray(const T* _ptr, size_t _length) : ptr(_ptr), length(_length) {} bool operator==(SliceArray &t) { return length == t.length && (memcmp(ptr,t.ptr, length*sizeof(T)) == 0); } /// Only use this for stings bool operator==(const char* str) { return str[length] == 0 && (strncmp(ptr, str, length) == 0); } /** This allocates a copy of the data. Only use this for debugging and error messages. */ std::string toString() { return std::string(ptr,length); } }; typedef SliceArray SString; typedef SliceArray IntArray; typedef SliceArray FloatArray; class NIFFile { enum NIFVersion { VER_MW = 0x04000002 // Morrowind NIFs }; /// Nif file version int ver; /// Input stream StreamPtr inp; /// File name, used for error messages std::string filename; /// Record list typedef void NifRecord; std::vector records; /// Used for error handling void fail(const std::string &msg) { std::string err = "NIFFile Error: " + msg; err += "\nFile: " + filename; throw str_exception(err); } /// Parse the file void parse() { // Check the header string const char* head = getString(40); if(!begins(head, "NetImmerse File Format")) fail("Invalid NIF header"); // Get BCD version ver = getInt(); if(ver != VER_MW) fail("Unsupported NIF version"); // Number of records int recNum = getInt(); records.resize(recNum); for(int i=0;i X getType() { return *((X*)inp->getPtr(sizeof(X))); } int getInt() { return getType(); } template SliceArray getArray() { int len = getInt(); return SliceArray((const X*)inp->getPtr(len), len); } SString getString() { return getArray(); } const char *getString(int size) { return (const char*)inp->getPtr(size); } }; #endif