gzreader.cpp 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #ifdef READER_CPP
  2. #include "gzreader.hpp"
  3. unsigned GZReader::size() {
  4. return filesize;
  5. }
  6. //This function will allocate memory even if open() fails.
  7. //This is needed so that when SRAM files do not exist, the
  8. //memory for the SRAM data will be allocated still.
  9. //The memory is flushed to 0x00 when no file is opened.
  10. uint8_t* GZReader::read(unsigned length) {
  11. uint8_t *data = 0;
  12. if(length == 0) {
  13. //read the entire file into RAM
  14. data = new(zeromemory) uint8_t[filesize];
  15. if(gp) gzread(gp, data, filesize);
  16. } else if(length > filesize) {
  17. //read the entire file into RAM, pad the rest with 0x00s
  18. data = new(zeromemory) uint8_t[length];
  19. if(gp) gzread(gp, data, filesize);
  20. } else { //filesize >= length
  21. //read only what was requested
  22. data = new(zeromemory) uint8_t[length];
  23. if(gp) gzread(gp, data, length);
  24. }
  25. return data;
  26. }
  27. bool GZReader::ready() {
  28. return (gp != 0);
  29. }
  30. GZReader::GZReader(const char *fn) : gp(0) {
  31. #if !defined(_WIN32)
  32. fp = fopen(fn, "rb");
  33. #else
  34. fp = _wfopen(utf16_t(fn), L"rb");
  35. #endif
  36. if(!fp) return;
  37. fseek(fp, 0, SEEK_END);
  38. filesize = ftell(fp);
  39. if(filesize < 4) {
  40. //too small to be a valid GZ archive
  41. fclose(fp);
  42. fp = 0;
  43. return;
  44. }
  45. fseek(fp, -4, SEEK_END);
  46. unsigned gzsize;
  47. gzsize = fgetc(fp);
  48. gzsize |= fgetc(fp) << 8;
  49. gzsize |= fgetc(fp) << 16;
  50. gzsize |= fgetc(fp) << 24;
  51. fseek(fp, 0, SEEK_SET);
  52. //zlib does not support UTF-8 filenames on Windows,
  53. //thus _wfopen() wrapper above + fileno() wrapper here.
  54. gp = gzdopen(fileno(fp), "rb");
  55. if(!gp) return;
  56. if(gzdirect(gp) == false) filesize = gzsize;
  57. if(filesize == 0) {
  58. //archive is empty
  59. gzclose(gp);
  60. gp = 0;
  61. return;
  62. }
  63. }
  64. GZReader::~GZReader() {
  65. if(gp) {
  66. gzclose(gp);
  67. gp = 0;
  68. }
  69. }
  70. #endif //ifdef READER_CPP