Apakio.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "Apak.h"
  4. #define APAKMAKEWORD(a, b) ((unsigned short)(((unsigned char)(a)) | ((unsigned short)((unsigned char)(b))) << 8))
  5. extern void apakError(APAK_HANDLE * pHandle, char *cError);
  6. extern int apakReadError(int iError, APAK_HANDLE * pHandle);
  7. int apakDir(APAK_HANDLE * pHandle, char *cFileName)
  8. {
  9. char buffer[256];
  10. int j, i = strlen(cFileName);
  11. for (j = i; j >= 0; j--)
  12. // if(cFileName[j] == '\\') - DIR?
  13. if (cFileName[j] == '/')
  14. break;
  15. if (j <= 0)
  16. return 1;
  17. strncpy(buffer, cFileName, j);
  18. buffer[j] = '\0';
  19. if (achdir(pHandle, buffer) == -1)
  20. return 0;
  21. strncpy(buffer, &cFileName[j + 1], strlen(cFileName) - j);
  22. buffer[strlen(cFileName) - j] = '\0';
  23. strcpy(cFileName, buffer);
  24. return 1;
  25. }
  26. APAKFILE *apakFile(APAK_HANDLE * pHandle, char *cFileName)
  27. {
  28. int i;
  29. if (!pHandle->pActualNode->apuLSizeofFile)
  30. return NULL;
  31. for (i = 0; (unsigned) i < pHandle->pActualNode->apuLSizeofFile; i++)
  32. if (!strcasecmp(cFileName, pHandle->pActualNode->apakFile[i].cName))
  33. return &pHandle->pActualNode->apakFile[i];
  34. return NULL;
  35. }
  36. int fillbuffer(APAK_FILE_HANDLE * pFHandle)
  37. {
  38. int err = 0;
  39. char *pTmp;
  40. uLongf rsize, size;
  41. rsize = pFHandle->pFileInfo->apuLRealSizeofFile;
  42. size = pFHandle->pFileInfo->apuLSizeofFile;
  43. pTmp = (char *) malloc(size);
  44. if (!pTmp)
  45. return 0;
  46. fseek(pFHandle->pArchive->pFILE, pFHandle->apuLfStartofFile, SEEK_SET);
  47. fread(pTmp, size, 1, pFHandle->pArchive->pFILE);
  48. if (pFHandle->pFileInfo->bNotCompressed)
  49. memcpy(pFHandle->pBuffer, pTmp, size);
  50. else
  51. err =
  52. uncompress((Bytef *) pFHandle->pBuffer, &rsize, (Bytef *) pTmp, size);
  53. free((void *) pTmp);
  54. if (err == Z_MEM_ERROR || err == Z_BUF_ERROR || err == Z_DATA_ERROR)
  55. return 0;
  56. return 1;
  57. }
  58. FILE *aopen(APAK_HANDLE * pHandle, const char *filename, const char *mode)
  59. {
  60. APAKNODE *pNode;
  61. APAK_FILE_HANDLE *pFHandle = NULL;
  62. APAK_STREAM_TYPE *pAStream = NULL;
  63. pAStream = (APAK_STREAM_TYPE *) malloc(sizeof(APAK_STREAM_TYPE));
  64. if (!pAStream)
  65. return 0;
  66. memset(pAStream, 0, sizeof(APAK_STREAM_TYPE));
  67. // strandard i/o stream (fopen, fclose, ....)
  68. if (!pHandle) {
  69. pAStream->pFile = fopen(filename, mode);
  70. if (!pAStream->pFile) {
  71. free((void *) pAStream);
  72. pAStream = NULL;
  73. }
  74. return (FILE *) pAStream;
  75. }
  76. // APAK stream (aread, agets, aclose, ....)
  77. if (mode[0] == 'w') {
  78. apakError(pHandle, "It's impossible to write into archive");
  79. free((void *) pAStream);
  80. return 0;
  81. }
  82. if (!filename) {
  83. apakError(pHandle, "filename = NULL");
  84. free((void *) pAStream);
  85. return 0;
  86. }
  87. if (!strlen(filename)) {
  88. apakError(pHandle, "filename length = 0");
  89. free((void *) pAStream);
  90. return 0;
  91. }
  92. pNode = pHandle->pActualNode;
  93. if (!apakDir(pHandle, (char *) filename)) {
  94. apakError(pHandle, "File not found");
  95. free((void *) pAStream);
  96. return 0;
  97. }
  98. pFHandle = (APAK_FILE_HANDLE *) malloc(sizeof(APAK_FILE_HANDLE));
  99. if (!pFHandle) {
  100. apakError(pHandle, "Unable to allocate memory for file handle");
  101. return 0;
  102. free((void *) pAStream);
  103. }
  104. memset(pFHandle, 0, sizeof(APAK_FILE_HANDLE));
  105. pFHandle->pFileInfo = apakFile(pHandle, (char *) filename);
  106. if (!pFHandle->pFileInfo) {
  107. free((void *) pFHandle);
  108. free((void *) pAStream);
  109. apakError(pHandle, "File not found");
  110. pHandle->pActualNode = pNode;
  111. return 0;
  112. }
  113. pFHandle->apuLfCursor = 0;
  114. pFHandle->apuLfStartofFile = pFHandle->pFileInfo->apuLFileLocation;
  115. pFHandle->apuLfEndofFile =
  116. pFHandle->pFileInfo->apuLFileLocation +
  117. pFHandle->pFileInfo->apuLSizeofFile;
  118. pFHandle->pArchive = pHandle;
  119. pFHandle->bEof = 0;
  120. pHandle->pActualNode = pNode;
  121. pFHandle->pBuffer =
  122. (char *) malloc(pFHandle->pFileInfo->apuLRealSizeofFile);
  123. if (!pFHandle->pBuffer) {
  124. free((void *) pFHandle);
  125. free((void *) pAStream);
  126. apakError(pHandle, "Can't allocate memory for internal buffer");
  127. pHandle->pActualNode = pNode;
  128. return 0;
  129. }
  130. memset(pFHandle->pBuffer, 0, pFHandle->pFileInfo->apuLSizeofFile);
  131. if (!fillbuffer(pFHandle)) {
  132. free((void *) pFHandle);
  133. free((void *) pFHandle->pBuffer);
  134. free((void *) pAStream);
  135. apakError(pHandle, "Can't fill internal buffer");
  136. pHandle->pActualNode = pNode;
  137. return 0;
  138. }
  139. pAStream->pAHandle = pFHandle;
  140. return (FILE *) pAStream;
  141. }
  142. int aclose(FILE * stream)
  143. {
  144. APAK_STREAM_TYPE *pAStream = (APAK_STREAM_TYPE *) stream;
  145. APAK_FILE_HANDLE *pFHandle;
  146. if (!pAStream)
  147. return 0;
  148. if (pAStream->pFile) {
  149. free((void *) pAStream);
  150. return fclose(pAStream->pFile);
  151. }
  152. pFHandle = (APAK_FILE_HANDLE *) pAStream->pAHandle;
  153. if (!pFHandle)
  154. return EOF;
  155. if (pFHandle->pBuffer)
  156. free((void *) pFHandle->pBuffer);
  157. free((void *) pFHandle);
  158. free((void *) pAStream);
  159. return 0;
  160. }
  161. size_t aread(void *buffer, size_t size, size_t count, FILE * stream)
  162. {
  163. char *cbuffer = (char *) buffer;
  164. char *cbCursor = NULL;
  165. int iAddSize = 0;
  166. unsigned int readsize, iSize = 0;
  167. APAK_STREAM_TYPE *pAStream = (APAK_STREAM_TYPE *) stream;
  168. APAK_FILE_HANDLE *pFHandle;
  169. if (!pAStream)
  170. return 0;
  171. if (pAStream->pFile)
  172. return fread(buffer, size, count, pAStream->pFile);
  173. pFHandle = (APAK_FILE_HANDLE *) pAStream->pAHandle;
  174. if (!pFHandle)
  175. return 0;
  176. iSize = pFHandle->pFileInfo->apuLRealSizeofFile;
  177. if (pFHandle->apuLfCursor >= iSize) {
  178. pFHandle->bEof = 1;
  179. return 0;
  180. }
  181. cbCursor = &pFHandle->pBuffer[pFHandle->apuLfCursor];
  182. readsize = size * count;
  183. if (pFHandle->apuLfCursor + readsize > iSize) {
  184. readsize = iSize - pFHandle->apuLfCursor;
  185. pFHandle->bEof = 1;
  186. }
  187. memcpy(buffer, cbCursor, readsize);
  188. pFHandle->apuLfCursor += readsize;
  189. return readsize;
  190. }
  191. size_t awrite(const void *buffer, size_t size, size_t count, FILE * stream)
  192. {
  193. APAK_STREAM_TYPE *pAStream = (APAK_STREAM_TYPE *) stream;
  194. if (!pAStream)
  195. return 0;
  196. if (pAStream->pFile)
  197. return fwrite(buffer, size, count, pAStream->pFile);
  198. return 0;
  199. }
  200. int aeof(FILE * stream)
  201. {
  202. APAK_STREAM_TYPE *pAStream = (APAK_STREAM_TYPE *) stream;
  203. APAK_FILE_HANDLE *pFHandle;
  204. if (!pAStream)
  205. return 0;
  206. if (pAStream->pFile)
  207. return feof(pAStream->pFile);
  208. pFHandle = (APAK_FILE_HANDLE *) pAStream->pAHandle;
  209. if (!pFHandle)
  210. return 0;
  211. return pFHandle->bEof;
  212. }
  213. char *agets(char *string, int n, FILE * stream)
  214. {
  215. int iRet = 0, readsize, i;
  216. unsigned int iSize;
  217. char *cbCursor, cLast = 0, *Tmp;
  218. APAK_FILE_HANDLE *pFHandle;
  219. APAK_STREAM_TYPE *pAStream = (APAK_STREAM_TYPE *) stream;
  220. if (!pAStream)
  221. return 0;
  222. if (pAStream->pFile)
  223. return fgets(string, n, pAStream->pFile);
  224. pFHandle = (APAK_FILE_HANDLE *) pAStream->pAHandle;
  225. if (!pFHandle)
  226. return NULL;
  227. cbCursor = &pFHandle->pBuffer[pFHandle->apuLfCursor];
  228. iSize = pFHandle->pFileInfo->apuLRealSizeofFile;
  229. if (pFHandle->apuLfCursor >= iSize) {
  230. pFHandle->bEof = 1;
  231. return 0;
  232. }
  233. // memset(string, 0, n);
  234. n--;
  235. if (n < 1)
  236. return 0;
  237. if (iSize - pFHandle->apuLfCursor > (unsigned) n)
  238. readsize = n;
  239. else
  240. readsize = iSize - pFHandle->apuLfCursor;
  241. Tmp = string;
  242. for (i = 0; i < readsize; i++) {
  243. if ((*cbCursor == 13 && !(*(cbCursor + 1)) && pFHandle->bUni) ||
  244. (*cbCursor == 13 && !pFHandle->bUni)) {
  245. if (pFHandle->bUni) {
  246. cbCursor += 2;
  247. i += 2;
  248. }
  249. else {
  250. cbCursor++;
  251. i++;
  252. }
  253. }
  254. if (*cbCursor == 10)
  255. cLast = 1;
  256. *string = *cbCursor;
  257. cbCursor++;
  258. string++;
  259. if (cLast)
  260. break;
  261. }
  262. if (pFHandle->bUni) {
  263. *string = 0;
  264. string++;
  265. }
  266. *string = '\0';
  267. if (pFHandle->bUni)
  268. pFHandle->apuLfCursor += i + 2;
  269. else
  270. pFHandle->apuLfCursor += i + 1;
  271. /* if(pFHandle->apuLfCursor >= iSize)
  272. pFHandle->bEof = 1;*/
  273. return Tmp;
  274. }
  275. int aputs(const char *string, FILE * stream)
  276. {
  277. APAK_STREAM_TYPE *pAStream = (APAK_STREAM_TYPE *) stream;
  278. if (!pAStream)
  279. return 0;
  280. if (pAStream->pFile)
  281. return fputs(string, pAStream->pFile);
  282. return EOF;
  283. }
  284. long atell(FILE * stream)
  285. {
  286. APAK_STREAM_TYPE *pAStream = (APAK_STREAM_TYPE *) stream;
  287. APAK_FILE_HANDLE *pFHandle;
  288. if (!pAStream)
  289. return 0;
  290. if (pAStream->pFile)
  291. return ftell(pAStream->pFile);
  292. pFHandle = (APAK_FILE_HANDLE *) pAStream->pAHandle;
  293. if (!pFHandle)
  294. return 0;
  295. return pFHandle->apuLfCursor;
  296. }
  297. int aseek(FILE * stream, long offset, int origin)
  298. {
  299. APAK_STREAM_TYPE *pAStream = (APAK_STREAM_TYPE *) stream;
  300. APAK_FILE_HANDLE *pFHandle;
  301. if (!pAStream)
  302. return 0;
  303. if (pAStream->pFile)
  304. return fseek(pAStream->pFile, offset, origin);
  305. pFHandle = (APAK_FILE_HANDLE *) pAStream->pAHandle;
  306. if (!pFHandle)
  307. return 1;
  308. switch (origin) {
  309. case SEEK_CUR:
  310. pFHandle->apuLfCursor = pFHandle->apuLfCursor + offset;
  311. break;
  312. case SEEK_END:
  313. pFHandle->apuLfCursor =
  314. pFHandle->pFileInfo->apuLRealSizeofFile + offset;
  315. break;
  316. case SEEK_SET:
  317. pFHandle->apuLfCursor = offset;
  318. break;
  319. }
  320. if (pFHandle->apuLfCursor < 0)
  321. pFHandle->apuLfCursor = 0;
  322. if (pFHandle->apuLfCursor > pFHandle->pFileInfo->apuLRealSizeofFile)
  323. pFHandle->apuLfCursor = pFHandle->pFileInfo->apuLRealSizeofFile;
  324. pFHandle->bEof = 0;
  325. return 0;
  326. }
  327. int aunicode(FILE * stream)
  328. {
  329. APAK_STREAM_TYPE *pAStream = (APAK_STREAM_TYPE *) stream;
  330. APAK_FILE_HANDLE *pFHandle;
  331. if (!pAStream)
  332. return 0;
  333. if (pAStream->pFile)
  334. return 0;
  335. pFHandle = (APAK_FILE_HANDLE *) pAStream->pAHandle;
  336. if (!pFHandle)
  337. return 0;
  338. if (APAKMAKEWORD(pFHandle->pBuffer[0], pFHandle->pBuffer[1]) == 0xFEFF) {
  339. pFHandle->bUni = 1;
  340. return 1;
  341. }
  342. return 0;
  343. }