NXZipFile.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #include "NXFileObject.h"
  2. #include <new>
  3. #include "minizip/unzip.h"
  4. #include <nx/nxfile.h>
  5. #include <assert.h>
  6. class NXZipFile : NXFileObject
  7. {
  8. public:
  9. NXZipFile(unzFile zip_file);
  10. ~NXZipFile();
  11. /* NXFileObject implementation */
  12. ns_error_t Read(void *buffer, size_t bytes_requested, size_t *bytes_read);
  13. ns_error_t Write(const void *buffer, size_t bytes);
  14. ns_error_t Seek(uint64_t position);
  15. ns_error_t Tell(uint64_t *position);
  16. ns_error_t PeekByte(uint8_t *byte);
  17. ns_error_t Sync();
  18. ns_error_t Truncate();
  19. // TODO(benski) implementation EOF
  20. // TODO(benski) implement region locking
  21. private:
  22. unzFile zip_file;
  23. };
  24. NXZipFile::NXZipFile(unzFile zip_file) : zip_file(zip_file)
  25. {
  26. }
  27. NXZipFile::~NXZipFile()
  28. {
  29. if (zip_file) {
  30. unzCloseCurrentFile(zip_file);
  31. unzClose(zip_file);
  32. zip_file=0;
  33. }
  34. }
  35. /* NXFileObject implementation */
  36. ns_error_t NXZipFile::Read(void *buffer, size_t bytes_requested, size_t *bytes_read)
  37. {
  38. int zret = unzReadCurrentFile(zip_file, buffer, (unsigned int)bytes_requested);
  39. if (zret == 0) {
  40. if (bytes_read) {
  41. *bytes_read = 0;
  42. }
  43. return NErr_EndOfFile;
  44. } else if (zret > 0) {
  45. if (bytes_read) {
  46. *bytes_read = (size_t)zret;
  47. }
  48. return NErr_Success;
  49. } else {
  50. if (bytes_read) {
  51. *bytes_read = 0;
  52. }
  53. return NErr_Error;
  54. }
  55. }
  56. ns_error_t NXZipFile::Write(const void *buffer, size_t bytes)
  57. {
  58. return NErr_NotImplemented;
  59. }
  60. ns_error_t NXZipFile::Seek(uint64_t position)
  61. {
  62. // TODO(benski) error check)
  63. unzSetOffset64(zip_file, position);
  64. return NErr_Success;
  65. }
  66. ns_error_t NXZipFile::Tell(uint64_t *position)
  67. {
  68. *position = unzGetOffset64(zip_file);
  69. return NErr_Success;
  70. }
  71. ns_error_t NXZipFile::PeekByte(uint8_t *byte)
  72. {
  73. return NErr_NotImplemented;
  74. }
  75. ns_error_t NXZipFile::Sync()
  76. {
  77. return NErr_NotImplemented;
  78. }
  79. ns_error_t NXZipFile::Truncate()
  80. {
  81. return NErr_NotImplemented;
  82. }
  83. static voidpf ZCALLBACK unzip_nxfile_open OF((voidpf opaque, const void* filename, int mode))
  84. {
  85. nx_file_t f;
  86. if (NXFileOpenFile(&f, (nx_uri_t)filename, nx_file_FILE_read_binary) != NErr_Success) {
  87. return 0;
  88. }
  89. return f;
  90. }
  91. static uLong ZCALLBACK unzip_nxfile_read OF((voidpf opaque, voidpf stream, void* buf, uLong size))
  92. {
  93. nx_file_t f = (nx_file_t)stream;
  94. size_t bytes_read;
  95. if (NXFileRead(f, buf, size, &bytes_read) != NErr_Success) {
  96. return 0;
  97. }
  98. return (uLong)bytes_read;
  99. }
  100. static int ZCALLBACK unzip_nxfile_close OF((voidpf opaque, voidpf stream))
  101. {
  102. NXFileRelease((nx_file_t)stream);
  103. return 0;
  104. }
  105. static ZPOS64_T ZCALLBACK unzip_nxfile_tell OF((voidpf opaque, voidpf stream))
  106. {
  107. nx_file_t f = (nx_file_t)stream;
  108. uint64_t position;
  109. if (NXFileTell(f, &position) == NErr_Success) {
  110. return (int64_t)position;
  111. } else {
  112. return -1;
  113. }
  114. }
  115. static long ZCALLBACK unzip_nxfile_seek OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int whence))
  116. {
  117. nx_file_t f = (nx_file_t)stream;
  118. uint64_t position;
  119. if (whence == SEEK_SET) {
  120. position = offset;
  121. } else if (whence == SEEK_CUR) {
  122. ns_error_t err = NXFileTell(f, &position);
  123. if (err != NErr_Success) {
  124. return -1;
  125. }
  126. position += offset;
  127. } else if (whence == SEEK_END) {
  128. uint64_t length;
  129. NXFileLength(f, &length);
  130. position = length + offset;
  131. } else {
  132. return -1;
  133. }
  134. ns_error_t err = NXFileSeek(f, position);
  135. if (err == NErr_Success) {
  136. return 0;
  137. } else {
  138. return -1;
  139. }
  140. }
  141. #if 0
  142. open64_file_func zopen64_file;
  143. read_file_func zread_file;
  144. write_file_func zwrite_file;
  145. tell64_file_func ztell64_file;
  146. seek64_file_func zseek64_file;
  147. close_file_func zclose_file;
  148. testerror_file_func zerror_file;
  149. #endif
  150. ns_error_t NXFileOpenZip(nx_file_t *out_file, nx_uri_t filename, nx_string_t extension_hint)
  151. {
  152. #if 0
  153. typedef struct zlib_filefunc_def_s
  154. {
  155. open_file_func zopen_file;
  156. read_file_func zread_file;
  157. write_file_func zwrite_file;
  158. tell_file_func ztell_file;
  159. seek_file_func zseek_file;
  160. close_file_func zclose_file;
  161. testerror_file_func zerror_file;
  162. voidpf opaque;
  163. } zlib_filefunc_def;
  164. #endif
  165. zlib_filefunc64_def file_func = {0, };
  166. file_func.zopen64_file = unzip_nxfile_open;
  167. file_func.zread_file = unzip_nxfile_read;
  168. file_func.ztell64_file = unzip_nxfile_tell;
  169. file_func.zseek64_file = unzip_nxfile_seek;
  170. file_func.zclose_file = unzip_nxfile_close;
  171. unzFile zip_file = unzOpen2_64(filename, &file_func);
  172. if (zip_file == NULL) {
  173. return NErr_Error;
  174. }
  175. unzGoToFirstFile(zip_file);
  176. // TODO(benski): look for filename with extension_hint as extension
  177. // TODO(benski): search for anything with extension
  178. unzOpenCurrentFile(zip_file);
  179. NXZipFile *nx_zip_file = new (std::nothrow) NXZipFile(zip_file);
  180. if (!nx_zip_file) {
  181. unzCloseCurrentFile(zip_file);
  182. unzClose(zip_file);
  183. return NErr_OutOfMemory;
  184. }
  185. *out_file = (nx_file_t)nx_zip_file;
  186. return NErr_Success;
  187. }