mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
Derive CSndHandler and CVidHandler from new class CMediaHandler.
This commit is contained in:
@@ -13,7 +13,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CSndHandler::~CSndHandler()
|
CMediaHandler::~CMediaHandler()
|
||||||
{
|
{
|
||||||
entries.clear();
|
entries.clear();
|
||||||
fimap.clear();
|
fimap.clear();
|
||||||
@@ -25,7 +25,7 @@ CSndHandler::~CSndHandler()
|
|||||||
// a simple structure. However, some post treatment would be necessary: file
|
// a simple structure. However, some post treatment would be necessary: file
|
||||||
// size and offsets are little endian, and filename have a NUL in
|
// size and offsets are little endian, and filename have a NUL in
|
||||||
// them. */
|
// them. */
|
||||||
CSndHandler::CSndHandler(std::string fname)
|
CMediaHandler::CMediaHandler(std::string fname)
|
||||||
{
|
{
|
||||||
try //c-tor of mapped_file_source throws exception on failure
|
try //c-tor of mapped_file_source throws exception on failure
|
||||||
{
|
{
|
||||||
@@ -36,7 +36,97 @@ CSndHandler::CSndHandler(std::string fname)
|
|||||||
tlog1 << "Cannot open " << fname << std::endl;
|
tlog1 << "Cannot open " << fname << std::endl;
|
||||||
throw std::string("Cannot open ")+fname;
|
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;i<entries.size();++i)
|
||||||
|
{
|
||||||
|
if (entries[i].name==srcfile)
|
||||||
|
extract(i,dstfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::transform(srcfile.begin(),srcfile.end(),srcfile.begin(),tolower);
|
||||||
|
for (size_t i=0;i<entries.size();++i)
|
||||||
|
{
|
||||||
|
if (entries[i].name==srcfile)
|
||||||
|
{
|
||||||
|
std::string por = entries[i].name;
|
||||||
|
std::transform(por.begin(),por.end(),por.begin(),tolower);
|
||||||
|
if (por==srcfile)
|
||||||
|
extract(i,dstfile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// unused and not sure what it's supposed to do
|
||||||
|
MemberFile CMediaHandler::getFile(std::string name)
|
||||||
|
{
|
||||||
|
MemberFile ret;
|
||||||
|
std::transform(name.begin(),name.end(),name.begin(),tolower);
|
||||||
|
for (size_t i=0;i<entries.size();++i)
|
||||||
|
{
|
||||||
|
if (entries[i].name==name)
|
||||||
|
{
|
||||||
|
std::string por = entries[i].name;
|
||||||
|
std::transform(por.begin(),por.end(),por.begin(),tolower);
|
||||||
|
if (por==name)
|
||||||
|
{
|
||||||
|
ret.length=entries[i].size;
|
||||||
|
file.seekg(entries[i].offset,std::ios_base::beg);
|
||||||
|
ret.ifs=&file;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char * CMediaHandler::extract (int index, int & size)
|
||||||
|
{
|
||||||
|
size = entries[index].size;
|
||||||
|
const char *data = mfile->data();
|
||||||
|
|
||||||
|
return &data[entries[index].offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
const char * CMediaHandler::extract (std::string srcName, int &size)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
std::map<std::string, int>::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::CMediaHandler(fname)
|
||||||
|
{
|
||||||
const unsigned char *data = (const unsigned char *)mfile->data();
|
const unsigned char *data = (const unsigned char *)mfile->data();
|
||||||
|
|
||||||
unsigned int numFiles = readNormalNr(&data[0]);
|
unsigned int numFiles = readNormalNr(&data[0]);
|
||||||
@@ -75,209 +165,48 @@ CSndHandler::CSndHandler(std::string fname)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads a 4 byte integer. Format on file is little endian.
|
CVidHandler::CVidHandler(std::string fname) : CMediaHandler::CMediaHandler(fname)
|
||||||
unsigned int CSndHandler::readNormalNr (const unsigned char *p)
|
|
||||||
{
|
{
|
||||||
return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
|
const unsigned char *data = (const unsigned char *)mfile->data();
|
||||||
}
|
|
||||||
|
|
||||||
void CSndHandler::extract(int index, std::string dstfile) //saves selected file
|
unsigned int numFiles = readNormalNr(&data[0]);
|
||||||
{
|
|
||||||
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 CSndHandler::extract(std::string srcfile, std::string dstfile, bool caseSens) //saves selected file
|
for (unsigned int i=0; i<numFiles; i++)
|
||||||
{
|
|
||||||
if (caseSens)
|
|
||||||
{
|
|
||||||
for (size_t i=0;i<entries.size();++i)
|
|
||||||
{
|
|
||||||
if (entries[i].name==srcfile)
|
|
||||||
extract(i,dstfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::transform(srcfile.begin(),srcfile.end(),srcfile.begin(),tolower);
|
|
||||||
for (size_t i=0;i<entries.size();++i)
|
|
||||||
{
|
|
||||||
if (entries[i].name==srcfile)
|
|
||||||
{
|
|
||||||
std::string por = entries[i].name;
|
|
||||||
std::transform(por.begin(),por.end(),por.begin(),tolower);
|
|
||||||
if (por==srcfile)
|
|
||||||
extract(i,dstfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// unused and not sure what it's supposed to do
|
|
||||||
MemberFile CSndHandler::getFile(std::string name)
|
|
||||||
{
|
|
||||||
MemberFile ret;
|
|
||||||
std::transform(name.begin(),name.end(),name.begin(),tolower);
|
|
||||||
for (size_t i=0;i<entries.size();++i)
|
|
||||||
{
|
|
||||||
if (entries[i].name==name)
|
|
||||||
{
|
|
||||||
std::string por = entries[i].name;
|
|
||||||
std::transform(por.begin(),por.end(),por.begin(),tolower);
|
|
||||||
if (por==name)
|
|
||||||
{
|
|
||||||
ret.length=entries[i].size;
|
|
||||||
file.seekg(entries[i].offset,std::ios_base::beg);
|
|
||||||
ret.ifs=&file;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const char * CSndHandler::extract (int index, int & size)
|
|
||||||
{
|
|
||||||
size = entries[index].size;
|
|
||||||
const char *data = mfile->data();
|
|
||||||
|
|
||||||
return &data[entries[index].offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * CSndHandler::extract (std::string srcName, int &size)
|
|
||||||
{
|
|
||||||
int index;
|
|
||||||
std::map<std::string, int>::iterator fit;
|
|
||||||
if ((fit = fimap.find(srcName)) != fimap.end())
|
|
||||||
{
|
|
||||||
index = fit->second;
|
|
||||||
return this->extract(index, size);
|
|
||||||
}
|
|
||||||
size = 0;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CVidHandler::~CVidHandler()
|
|
||||||
{
|
|
||||||
entries.clear();
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
CVidHandler::CVidHandler(std::string fname):CHUNK(65535)
|
|
||||||
{
|
|
||||||
file.open(fname.c_str(),std::ios::binary);
|
|
||||||
if (!file.is_open())
|
|
||||||
#ifndef __GNUC__
|
|
||||||
throw new std::exception((std::string("Cannot open ")+fname).c_str());
|
|
||||||
#else
|
|
||||||
throw new std::exception();
|
|
||||||
#endif
|
|
||||||
int nr = readNormalNr(0,4);
|
|
||||||
char tempc;
|
|
||||||
for (int i=0;i<nr;i++)
|
|
||||||
{
|
{
|
||||||
Entry entry;
|
Entry entry;
|
||||||
while(true)
|
const unsigned char *p;
|
||||||
{
|
|
||||||
file.read(&tempc,1);
|
// Read file name and extension
|
||||||
if (tempc)
|
p = &data[4+44*i];
|
||||||
entry.name+=tempc;
|
|
||||||
else break;
|
while(*p) {
|
||||||
|
entry.name += *p;
|
||||||
|
p++;
|
||||||
}
|
}
|
||||||
entry.something=readNormalNr(-1,4);
|
|
||||||
file.seekg(44-entry.name.length()-9,std::ios_base::cur);
|
entry.name+='.';
|
||||||
entry.offset = readNormalNr(-1,4);
|
p++;
|
||||||
if (i>0)
|
|
||||||
entries[i-1].size=entry.offset-entries[i-1].offset;
|
while(*p)
|
||||||
if (i==nr-1)
|
|
||||||
{
|
{
|
||||||
file.seekg(0,std::ios::end);
|
entry.name += *p;
|
||||||
entry.size = ((int)file.tellg())-entry.offset;
|
p++;
|
||||||
file.seekg(0,std::ios::beg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read offset and size
|
||||||
|
p = &data[4+44*i+40];
|
||||||
|
entry.offset = readNormalNr(p);
|
||||||
|
|
||||||
|
// There is no size, so check where the next file is
|
||||||
|
if (i == numFiles - 1) {
|
||||||
|
entry.size = mfile->size() - 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);
|
entries.push_back(entry);
|
||||||
|
fimap[entry.name] = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int CVidHandler::readNormalNr (int pos, int bytCon)
|
|
||||||
{
|
|
||||||
if (pos>=0)
|
|
||||||
file.seekg(pos,std::ios_base::beg);
|
|
||||||
int ret=0;
|
|
||||||
int amp=1;
|
|
||||||
unsigned char zcz=0;
|
|
||||||
for (int i=0; i<bytCon; i++)
|
|
||||||
{
|
|
||||||
file.read((char*)(&zcz),1);
|
|
||||||
ret+=zcz*amp;
|
|
||||||
amp*=256;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
void CVidHandler::extract(int index, std::string dstfile) //saves selected file
|
|
||||||
{
|
|
||||||
std::ofstream out(dstfile.c_str(),std::ios_base::binary);
|
|
||||||
file.seekg(entries[index].offset,std::ios_base::beg);
|
|
||||||
int toRead=entries[index].size;
|
|
||||||
char * buffer = new char[std::min(CHUNK,entries[index].size)];
|
|
||||||
while (toRead>CHUNK)
|
|
||||||
{
|
|
||||||
file.read(buffer,CHUNK);
|
|
||||||
out.write(buffer,CHUNK);
|
|
||||||
toRead-=CHUNK;
|
|
||||||
}
|
|
||||||
file.read(buffer,toRead);
|
|
||||||
out.write(buffer,toRead);
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
void CVidHandler::extract(std::string srcfile, std::string dstfile, bool caseSens) //saves selected file
|
|
||||||
{
|
|
||||||
if (caseSens)
|
|
||||||
{
|
|
||||||
for (size_t i=0;i<entries.size();++i)
|
|
||||||
{
|
|
||||||
if (entries[i].name==srcfile)
|
|
||||||
extract(i,dstfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::transform(srcfile.begin(),srcfile.end(),srcfile.begin(),tolower);
|
|
||||||
for (size_t i=0;i<entries.size();++i)
|
|
||||||
{
|
|
||||||
if (entries[i].name==srcfile)
|
|
||||||
{
|
|
||||||
std::string por = entries[i].name;
|
|
||||||
std::transform(por.begin(),por.end(),por.begin(),tolower);
|
|
||||||
if (por==srcfile)
|
|
||||||
extract(i,dstfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MemberFile CVidHandler::getFile(std::string name)
|
|
||||||
{
|
|
||||||
MemberFile ret;
|
|
||||||
std::transform(name.begin(),name.end(),name.begin(),tolower);
|
|
||||||
for (size_t i=0;i<entries.size();++i)
|
|
||||||
{
|
|
||||||
if (entries[i].name==name)
|
|
||||||
{
|
|
||||||
std::string por = entries[i].name;
|
|
||||||
std::transform(por.begin(),por.end(),por.begin(),tolower);
|
|
||||||
if (por==name)
|
|
||||||
{
|
|
||||||
ret.length=entries[i].size;
|
|
||||||
file.seekg(entries[i].offset,std::ios_base::beg);
|
|
||||||
ret.ifs=&file;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw ret;
|
|
||||||
//return ret;
|
|
||||||
}
|
|
||||||
|
@@ -29,9 +29,10 @@ struct MemberFile
|
|||||||
std::ifstream * ifs;
|
std::ifstream * ifs;
|
||||||
int length;
|
int length;
|
||||||
};
|
};
|
||||||
class CSndHandler
|
|
||||||
|
class CMediaHandler
|
||||||
{
|
{
|
||||||
private:
|
protected:
|
||||||
struct Entry
|
struct Entry
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
@@ -44,36 +45,26 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
std::vector<Entry> entries;
|
std::vector<Entry> entries;
|
||||||
std::map<std::string, int> fimap; // map of wav file and index
|
std::map<std::string, int> fimap; // map of file and index
|
||||||
~CSndHandler(); //d-tor
|
~CMediaHandler(); //d-tor
|
||||||
CSndHandler(std::string fname); //c-tor
|
CMediaHandler(std::string fname); //c-tor
|
||||||
void extract(std::string srcfile, std::string dstfile, bool caseSens=true); //saves selected file
|
void extract(std::string srcfile, std::string dstfile, bool caseSens=true); //saves selected file
|
||||||
const char * extract (std::string srcfile, int & size); //return selecte file data, NULL if file doesn't exist
|
const char * extract (std::string srcfile, int & size); //return selecte file data, NULL if file doesn't exist
|
||||||
void extract(int index, std::string dstfile); //saves selected file
|
void extract(int index, std::string dstfile); //saves selected file
|
||||||
MemberFile getFile(std::string name);//nie testowane - sprawdzic
|
MemberFile getFile(std::string name);//nie testowane - sprawdzic
|
||||||
const char * extract (int index, int & size); //return selecte file - NIE TESTOWANE
|
const char * extract (int index, int & size); //return selecte file - NIE TESTOWANE
|
||||||
};
|
};
|
||||||
class CVidHandler
|
|
||||||
|
class CSndHandler: public CMediaHandler
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
const int CHUNK;
|
|
||||||
struct Entry
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
int size, offset, something;
|
|
||||||
};
|
|
||||||
std::ifstream file;
|
|
||||||
int readNormalNr (int pos, int bytCon);
|
|
||||||
bool opened;
|
|
||||||
public:
|
public:
|
||||||
std::vector<Entry> entries;
|
CSndHandler(std::string fname);
|
||||||
~CVidHandler(); //d-tor
|
};
|
||||||
CVidHandler(std::string fname); //c-tor
|
|
||||||
std::ifstream & extract(std::string srcfile);
|
class CVidHandler: public CMediaHandler
|
||||||
void extract(std::string srcfile, std::string dstfile, bool caseSens=true); //saves selected file
|
{
|
||||||
unsigned char * extract (std::string srcfile, int & size); //return selecte file,
|
public:
|
||||||
void extract(int index, std::string dstfile); //saves selected file
|
CVidHandler(std::string fname);
|
||||||
MemberFile getFile(std::string name); //nie testowane - sprawdzic
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user