#include "../stdafx.h" #include #include "CSndHandler.h" #include #include /* * CSndHandler.cpp, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * * License: GNU General Public License v2.0 or later * Full text of license available in license.txt file, in main folder * */ CMediaHandler::~CMediaHandler() { entries.clear(); fimap.clear(); mfile->close(); delete mfile; } CMediaHandler::CMediaHandler(std::string fname) { try //c-tor of mapped_file_source throws exception on failure { mfile = new boost::iostreams::mapped_file_source(fname); } HANDLE_EXCEPTIONC(tlog1 << "Cannot open " << fname << std::endl) if (!mfile->is_open()) //just in case { tlog1 << "Cannot open " << fname << std::endl; throw std::string("Cannot open ")+fname; } } void CMediaHandler::extract(int index, std::string dstfile) //saves selected file { std::ofstream out(dstfile.c_str(),std::ios_base::binary); const char *data = mfile->data(); out.write(&data[entries[index].offset], entries[index].size); out.close(); } void CMediaHandler::extract(std::string srcfile, std::string dstfile, bool caseSens) //saves selected file { srcfile.erase(srcfile.find_last_of('.')); if (caseSens) { for (size_t i=0;idata(); return &data[entries[index].offset]; } const char * CMediaHandler::extract (std::string srcName, int &size) { int index; srcName.erase(srcName.find_last_of('.')); std::map::iterator fit; if ((fit = fimap.find(srcName)) != fimap.end()) { index = fit->second; return this->extract(index, size); } size = 0; return NULL; } CSndHandler::CSndHandler(std::string fname) : CMediaHandler(fname) { const unsigned char *data = (const unsigned char *)mfile->data(); unsigned int numFiles = SDL_SwapLE32(*(Uint32 *)&data[0]); struct soundEntry *se = (struct soundEntry *)&data[4]; for (unsigned int i=0; ifilename; // entry.name += '.'; // p = se->filename; // while(*p) p++; // p++; // entry.name += p; entry.offset = SDL_SwapLE32(se->offset); entry.size = SDL_SwapLE32(se->size); entries.push_back(entry); fimap[entry.name] = i; } } CVidHandler::CVidHandler(std::string fname) : CMediaHandler(fname) { if(mfile->size() < 48) { tlog1 << fname << " doesn't contain needed data!\n"; return; } const unsigned char *data = (const unsigned char *)mfile->data(); unsigned int numFiles = SDL_SwapLE32(*(Uint32 *)&data[0]); struct videoEntry *ve = (struct videoEntry *)&data[4]; for (unsigned int i=0; ifilename; entry.offset = SDL_SwapLE32(ve->offset); entry.name.erase(entry.name.find_last_of('.')); // There is no size, so check where the next file is if (i == numFiles - 1) { entry.size = mfile->size() - entry.offset; } else { struct videoEntry *ve_next = ve+1; entry.size = SDL_SwapLE32(ve_next->offset) - entry.offset; } entries.push_back(entry); fimap[entry.name] = i; } }