1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00

* added CVidHandler for handling .vid files

This commit is contained in:
Michał W. Urbańczyk 2007-07-31 05:24:10 +00:00
parent b2d1b4f3e4
commit d1615be5ec
2 changed files with 165 additions and 1 deletions

View File

@ -94,6 +94,27 @@ void CSndHandler::extract(std::string srcfile, std::string dstfile, bool caseSen
}
}
}
MemberFile CSndHandler::getFile(std::string name)
{
MemberFile ret;
std::transform(name.begin(),name.end(),name.begin(),tolower);
for (int 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;
}
unsigned char * CSndHandler::extract (int index, int & size)
{
size = entries[index].size;
@ -101,4 +122,119 @@ unsigned char * CSndHandler::extract (int index, int & size)
file.seekg(entries[index].offset,std::ios_base::beg);
file.read((char*)ret,entries[index].size);
return ret;
}
}
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())
throw new std::exception((std::string("Cannot open ")+fname).c_str());
int nr = readNormalNr(0,4);
char tempc;
for (int i=0;i<nr;i++)
{
Entry entry;
while(true)
{
file.read(&tempc,1);
if (tempc)
entry.name+=tempc;
else break;
}
entry.something=readNormalNr(-1,4);
file.seekg(44-entry.name.length()-9,std::ios_base::cur);
entry.offset = readNormalNr(-1,4);
if (i>0)
entries[i-1].size=entry.offset-entries[i-1].offset;
if (i==nr-1)
{
file.seekg(0,std::ios::end);
entry.size = ((int)file.tellg())-entry.offset;
file.seekg(0,std::ios::beg);
}
entries.push_back(entry);
}
}
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 (int 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 (int 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 (int 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;
}

View File

@ -3,6 +3,11 @@
#include <vector>
#include <fstream>
struct MemberFile
{
std::ifstream * ifs;
int length;
};
class CSndHandler
{
protected:
@ -22,7 +27,30 @@ public:
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
void extract(int index, std::string dstfile); //saves selected file
MemberFile getFile(std::string name);//nie testowane - sprawdzic
unsigned char * extract (int index, int & size); //return selecte file - NIE TESTOWANE
};
class CVidHandler
{
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:
std::vector<Entry> entries;
~CVidHandler();
CVidHandler(std::string fname);
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
void extract(int index, std::string dstfile); //saves selected file
MemberFile getFile(std::string name); //nie testowane - sprawdzic
};
#endif //CSNDHANDLER_H