/////////////////////////////////////////////////////////////////////////////// // // Name: FileUnpacker.cpp // Author: Rich Cross // Contact: rich@wildfiregames.com // /////////////////////////////////////////////////////////////////////////////// #include "precompiled.h" #include "FileUnpacker.h" #include "res/vfs.h" //////////////////////////////////////////////////////////////////////////////////////// // CFileUnpacker constructor CFileUnpacker::CFileUnpacker() : m_UnpackPos(0), m_Version(0) { } //////////////////////////////////////////////////////////////////////////////////////// // Read: open and read in given file, check magic bits against those given; throw // variety of exceptions for missing files etc void CFileUnpacker::Read(const char* filename,const char magicstr[4]) { // load the whole thing into memory void* file; size_t size; Handle hm = vfs_load(filename, file, size); if(hm <= 0) throw CFileOpenError(); // make sure we read enough for the header if(size < 12) { mem_free_h(hm); throw CFileReadError(); } // extract data from header u8* header = (u8*)file; char* magic = (char*)(header+0); m_Version = *(u32*)(header+4); u32 datasize = *(u32*)(header+8); void* data = (header+12); // check we've got the right kind of file // .. and that we read exactly headersize+datasize if(strncmp(magic, magicstr, 4) != 0 || size != 12+datasize) { mem_free_h(hm); throw CFileTypeError(); } // allocate memory and read in a big chunk of data m_Data.resize(datasize); memcpy(&m_Data[0], data, datasize); mem_free_h(hm); /* FILE* fp=fopen(filename,"rb"); if (!fp) { throw CFileOpenError(); } // read magic bits char magic[4]; if (fread(magic,sizeof(char)*4,1,fp)!=1) { fclose(fp); throw CFileReadError(); } // check we've got the right kind of file if (strncmp(magic,magicstr,4)!=0) { // nope .. fclose(fp); throw CFileTypeError(); } // get version if (fread(&m_Version,sizeof(m_Version),1,fp)!=1) { fclose(fp); throw CFileReadError(); } // get size of anim data u32 datasize; if (fread(&datasize,sizeof(datasize),1,fp)!=1) { fclose(fp); throw CFileReadError(); } // allocate memory and read in a big chunk of data m_Data.resize(datasize); if (fread(&m_Data[0],datasize,1,fp)!=1) { fclose(fp); throw CFileReadError(); } // all done fclose(fp); */ } //////////////////////////////////////////////////////////////////////////////////////// // UnpackRaw: unpack given number of bytes from the input stream into the given array // - throws CFileEOFError if the end of the data stream is reached before the given // number of bytes have been read void CFileUnpacker::UnpackRaw(void* rawdata,u32 rawdatalen) { // got enough data to unpack? if (m_UnpackPos+rawdatalen<=m_Data.size()) { // yes .. copy over memcpy(rawdata,&m_Data[m_UnpackPos],rawdatalen); // advance pointer m_UnpackPos+=rawdatalen; } else { // nope - throw exception throw CFileEOFError(); } } //////////////////////////////////////////////////////////////////////////////////////// // UnpackString: unpack a string from the raw data stream void CFileUnpacker::UnpackString(CStr& result) { // get string length u32 length; UnpackRaw(&length,sizeof(length)); // read string into temporary buffer std::vector tmp; tmp.resize(length+1); UnpackRaw(&tmp[0],length); tmp[length]='\0'; // assign to output result=&tmp[0]; }