CSndHandler.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. #include "../stdafx.h"
  2. #include "CSndHandler.h"
  3. /*
  4. * CSndHandler.cpp, part of VCMI engine
  5. *
  6. * Authors: listed in file AUTHORS in main folder
  7. *
  8. * License: GNU General Public License v2.0 or later
  9. * Full text of license available in license.txt file, in main folder
  10. *
  11. */
  12. CSndHandler::~CSndHandler()
  13. {
  14. entries.clear();
  15. fimap.clear();
  16. file.close();
  17. }
  18. CSndHandler::CSndHandler(std::string fname):CHUNK(65535)
  19. {
  20. file.open(fname.c_str(),std::ios::binary);
  21. if (!file.is_open())
  22. {
  23. tlog1 << "Cannot open " << fname << std::endl;
  24. throw std::string("Cannot open ")+fname;
  25. }
  26. int nr = readNormalNr(0,4);
  27. char tempc;
  28. for (int i=0;i<nr;i++)
  29. {
  30. Entry entry;
  31. while(true)
  32. {
  33. file.read(&tempc,1);
  34. if (tempc)
  35. entry.name+=tempc;
  36. else break;
  37. }
  38. entry.name+='.';
  39. while(true)
  40. {
  41. file.read(&tempc,1);
  42. if (tempc)
  43. entry.name+=tempc;
  44. else break;
  45. }
  46. file.seekg(40-entry.name.length()-1,std::ios_base::cur);
  47. entry.offset = readNormalNr(-1,4);
  48. entry.size = readNormalNr(-1,4);
  49. entries.push_back(entry);
  50. fimap[entry.name] = i;
  51. }
  52. }
  53. int CSndHandler::readNormalNr (int pos, int bytCon)
  54. {
  55. if (pos>=0)
  56. file.seekg(pos,std::ios_base::beg);
  57. int ret=0;
  58. int amp=1;
  59. unsigned char zcz=0;
  60. for (int i=0; i<bytCon; i++)
  61. {
  62. file.read((char*)(&zcz),1);
  63. ret+=zcz*amp;
  64. amp*=256;
  65. }
  66. return ret;
  67. }
  68. void CSndHandler::extract(int index, std::string dstfile) //saves selected file
  69. {
  70. std::ofstream out(dstfile.c_str(),std::ios_base::binary);
  71. file.seekg(entries[index].offset,std::ios_base::beg);
  72. int toRead=entries[index].size;
  73. char * buffer = new char[std::min(CHUNK,entries[index].size)];
  74. while (toRead>CHUNK)
  75. {
  76. file.read(buffer,CHUNK);
  77. out.write(buffer,CHUNK);
  78. toRead-=CHUNK;
  79. }
  80. file.read(buffer,toRead);
  81. out.write(buffer,toRead);
  82. out.close();
  83. }
  84. void CSndHandler::extract(std::string srcfile, std::string dstfile, bool caseSens) //saves selected file
  85. {
  86. if (caseSens)
  87. {
  88. for (size_t i=0;i<entries.size();++i)
  89. {
  90. if (entries[i].name==srcfile)
  91. extract(i,dstfile);
  92. }
  93. }
  94. else
  95. {
  96. std::transform(srcfile.begin(),srcfile.end(),srcfile.begin(),tolower);
  97. for (size_t i=0;i<entries.size();++i)
  98. {
  99. if (entries[i].name==srcfile)
  100. {
  101. std::string por = entries[i].name;
  102. std::transform(por.begin(),por.end(),por.begin(),tolower);
  103. if (por==srcfile)
  104. extract(i,dstfile);
  105. }
  106. }
  107. }
  108. }
  109. MemberFile CSndHandler::getFile(std::string name)
  110. {
  111. MemberFile ret;
  112. std::transform(name.begin(),name.end(),name.begin(),tolower);
  113. for (size_t i=0;i<entries.size();++i)
  114. {
  115. if (entries[i].name==name)
  116. {
  117. std::string por = entries[i].name;
  118. std::transform(por.begin(),por.end(),por.begin(),tolower);
  119. if (por==name)
  120. {
  121. ret.length=entries[i].size;
  122. file.seekg(entries[i].offset,std::ios_base::beg);
  123. ret.ifs=&file;
  124. return ret;
  125. }
  126. }
  127. }
  128. return ret;
  129. }
  130. unsigned char * CSndHandler::extract (int index, int & size)
  131. {
  132. size = entries[index].size;
  133. unsigned char * ret = new unsigned char[size];
  134. file.seekg(entries[index].offset,std::ios_base::beg);
  135. file.read((char*)ret,entries[index].size);
  136. return ret;
  137. }
  138. unsigned char * CSndHandler::extract (std::string srcName, int &size)
  139. {
  140. int index;
  141. std::map<std::string, int>::iterator fit;
  142. if ((fit = fimap.find(srcName)) != fimap.end())
  143. {
  144. index = fit->second;
  145. return this->extract(index, size);
  146. }
  147. size = 0;
  148. return NULL;
  149. }
  150. CVidHandler::~CVidHandler()
  151. {
  152. entries.clear();
  153. file.close();
  154. }
  155. CVidHandler::CVidHandler(std::string fname):CHUNK(65535)
  156. {
  157. file.open(fname.c_str(),std::ios::binary);
  158. if (!file.is_open())
  159. #ifndef __GNUC__
  160. throw new std::exception((std::string("Cannot open ")+fname).c_str());
  161. #else
  162. throw new std::exception();
  163. #endif
  164. int nr = readNormalNr(0,4);
  165. char tempc;
  166. for (int i=0;i<nr;i++)
  167. {
  168. Entry entry;
  169. while(true)
  170. {
  171. file.read(&tempc,1);
  172. if (tempc)
  173. entry.name+=tempc;
  174. else break;
  175. }
  176. entry.something=readNormalNr(-1,4);
  177. file.seekg(44-entry.name.length()-9,std::ios_base::cur);
  178. entry.offset = readNormalNr(-1,4);
  179. if (i>0)
  180. entries[i-1].size=entry.offset-entries[i-1].offset;
  181. if (i==nr-1)
  182. {
  183. file.seekg(0,std::ios::end);
  184. entry.size = ((int)file.tellg())-entry.offset;
  185. file.seekg(0,std::ios::beg);
  186. }
  187. entries.push_back(entry);
  188. }
  189. }
  190. int CVidHandler::readNormalNr (int pos, int bytCon)
  191. {
  192. if (pos>=0)
  193. file.seekg(pos,std::ios_base::beg);
  194. int ret=0;
  195. int amp=1;
  196. unsigned char zcz=0;
  197. for (int i=0; i<bytCon; i++)
  198. {
  199. file.read((char*)(&zcz),1);
  200. ret+=zcz*amp;
  201. amp*=256;
  202. }
  203. return ret;
  204. }
  205. void CVidHandler::extract(int index, std::string dstfile) //saves selected file
  206. {
  207. std::ofstream out(dstfile.c_str(),std::ios_base::binary);
  208. file.seekg(entries[index].offset,std::ios_base::beg);
  209. int toRead=entries[index].size;
  210. char * buffer = new char[std::min(CHUNK,entries[index].size)];
  211. while (toRead>CHUNK)
  212. {
  213. file.read(buffer,CHUNK);
  214. out.write(buffer,CHUNK);
  215. toRead-=CHUNK;
  216. }
  217. file.read(buffer,toRead);
  218. out.write(buffer,toRead);
  219. out.close();
  220. }
  221. void CVidHandler::extract(std::string srcfile, std::string dstfile, bool caseSens) //saves selected file
  222. {
  223. if (caseSens)
  224. {
  225. for (size_t i=0;i<entries.size();++i)
  226. {
  227. if (entries[i].name==srcfile)
  228. extract(i,dstfile);
  229. }
  230. }
  231. else
  232. {
  233. std::transform(srcfile.begin(),srcfile.end(),srcfile.begin(),tolower);
  234. for (size_t i=0;i<entries.size();++i)
  235. {
  236. if (entries[i].name==srcfile)
  237. {
  238. std::string por = entries[i].name;
  239. std::transform(por.begin(),por.end(),por.begin(),tolower);
  240. if (por==srcfile)
  241. extract(i,dstfile);
  242. }
  243. }
  244. }
  245. }
  246. MemberFile CVidHandler::getFile(std::string name)
  247. {
  248. MemberFile ret;
  249. std::transform(name.begin(),name.end(),name.begin(),tolower);
  250. for (size_t i=0;i<entries.size();++i)
  251. {
  252. if (entries[i].name==name)
  253. {
  254. std::string por = entries[i].name;
  255. std::transform(por.begin(),por.end(),por.begin(),tolower);
  256. if (por==name)
  257. {
  258. ret.length=entries[i].size;
  259. file.seekg(entries[i].offset,std::ios_base::beg);
  260. ret.ifs=&file;
  261. return ret;
  262. }
  263. }
  264. }
  265. throw ret;
  266. //return ret;
  267. }