#include "../stdafx.h" #include #include "CSndHandler.h" #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; } // Analyze the sound file. Half of this could go away if we were using // a simple structure. However, some post treatment would be necessary: file // size and offsets are little endian, and filename have a NUL in // them. */ 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_EXCEPTION if (!mfile->is_open()) //just in case { tlog1 << "Cannot open " << fname << std::endl; throw std::string("Cannot open ")+fname; } } // Reads a 4 byte integer. Format on file is little endian. unsigned int CMediaHandler::readNormalNr (const unsigned char *p) { return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); } 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 { if (caseSens) { for (size_t i=0;idata(); return &data[entries[index].offset]; } const char * CMediaHandler::extract (std::string srcName, int &size) { int index; 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 = readNormalNr(&data[0]); for (unsigned int i=0; idata(); unsigned int numFiles = readNormalNr(&data[0]); for (unsigned int i=0; isize() - entry.offset; } else { p = &data[4+44*(i+1)+40]; int next_offset = readNormalNr(p); entry.size = next_offset - entry.offset; } entries.push_back(entry); fimap[entry.name] = i; } }