zipme.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include "zipme.h"
  2. #include "zlib.h"
  3. ZipMe::ZipMe() : data(_FL_)
  4. {
  5. }
  6. ZipMe::~ZipMe()
  7. {
  8. data.Empty();
  9. }
  10. //Записать файл с архивацией, добавляеться последний символ в конец имени 'z'
  11. bool ZipMe::WriteFile(const char * fileName, const void * data, dword dataSize, bool isCompress)
  12. {
  13. if(!data || !dataSize) return false;
  14. IFileService * fs = (IFileService *)api->GetService("FileService");
  15. Assert(fs);
  16. if(isCompress)
  17. {
  18. string zipName(fileName);
  19. for(const char * c = fileName; *c; c++);
  20. if(c[-1] != 'z' && c[-1] != 'Z')
  21. {
  22. zipName += 'z';
  23. }
  24. fs->Delete(zipName.c_str());
  25. gzFile file = gzopen(zipName.c_str(), "w+b");
  26. if(!file) return false;
  27. gzsetparams(file, 2, Z_DEFAULT_STRATEGY);
  28. if(gzwrite(file, data, dataSize) != dataSize)
  29. {
  30. gzclose(file);
  31. fs->Delete(zipName.c_str());
  32. return false;
  33. }
  34. gzclose(file);
  35. }else{
  36. if(!fs->SaveData(fileName, data, dataSize))
  37. {
  38. return false;
  39. }
  40. }
  41. return true;
  42. }
  43. //Прочитать файл в память, если последний яимвол 'z' то подрузамеваеться что файл с компрессией
  44. bool ZipMe::ReadFile(const char * fileName)
  45. {
  46. if(!fileName || !fileName[0]) return false;
  47. IFileService * fs = (IFileService *)api->GetService("FileService");
  48. Assert(fs);
  49. //Сначала пробуем открыть zip файл, тк он по определению более новый
  50. string zipName = fileName;
  51. if(zipName.Last() != 'z' && zipName.Last() != 'Z')
  52. {
  53. zipName += 'z';
  54. }
  55. gzFile zipFile = gzopen(fileName, "rb");
  56. if(!zipFile)
  57. {
  58. zipName.Delete(zipName.Len() - 1, 1);
  59. IFile * file = fs->OpenFile(zipName, file_open_existing_for_read, _FL_);
  60. if(!file)
  61. {
  62. return false;
  63. }
  64. if(file->Size() > 0)
  65. {
  66. data.AddElements(file->Size());
  67. if(file->Read(data.GetBuffer(), data.Size()) != data.Size())
  68. {
  69. data.Empty();
  70. file->Release();
  71. return false;
  72. }
  73. }
  74. file->Release();
  75. return true;
  76. }
  77. long chank = 65536*4;
  78. while(true)
  79. {
  80. dword offset = data.Size();
  81. data.AddElements(chank);
  82. long readBytes = gzread(zipFile, &data[offset], chank);
  83. if(readBytes < 0)
  84. {
  85. gzclose(zipFile);
  86. data.Empty();
  87. return false;
  88. }
  89. if(readBytes < chank)
  90. {
  91. data.DelRange(offset + readBytes, data.Last());
  92. gzclose(zipFile);
  93. break;
  94. }
  95. }
  96. return true;
  97. }
  98. //Получить буфер
  99. const byte * ZipMe::Data()
  100. {
  101. return data.GetBuffer();
  102. }
  103. //Размер буфера
  104. dword ZipMe::Size()
  105. {
  106. return data.Size();
  107. }
  108. //Заменить в загруженном буфере все \r на \n и убрать двойные \n
  109. void ZipMe::ClearText()
  110. {
  111. long size = data.Size();
  112. if(!size) return;
  113. byte * buf = data.GetBuffer();
  114. for(long src = 1, dst = 1; src < data; src++)
  115. {
  116. if(buf[src] != '\r' && buf[src] != 0)
  117. {
  118. buf[dst++] = buf[src];
  119. }
  120. }
  121. if(dst < data)
  122. {
  123. data.DelRange(dst, data.Last());
  124. }
  125. data.Add(0);
  126. }