#include "stdafx.h" #include "CSndHandler.h" CSndHandler::~CSndHandler() { entries.clear(); file.close(); } CSndHandler::CSndHandler(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.name+='.'; while(true) { file.read(&tempc,1); if (tempc) entry.name+=tempc; else break; } file.seekg(40-entry.name.length()-1,std::ios_base::cur); entry.offset = readNormalNr(-1,4); entry.size = readNormalNr(-1,4); entries.push_back(entry); } } int CSndHandler::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 CSndHandler::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 CSndHandler::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 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; unsigned char * ret = new unsigned char[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; }