memzip.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #include <stdint.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "py/mpconfig.h"
  5. #include "py/misc.h"
  6. #include "memzip.h"
  7. extern uint8_t memzip_data[];
  8. const MEMZIP_FILE_HDR *memzip_find_file_header(const char *filename) {
  9. const MEMZIP_FILE_HDR *file_hdr = (const MEMZIP_FILE_HDR *)memzip_data;
  10. uint8_t *mem_data;
  11. /* Zip file filenames don't have a leading /, so we strip it off */
  12. if (*filename == '/') {
  13. filename++;
  14. }
  15. while (file_hdr->signature == MEMZIP_FILE_HEADER_SIGNATURE) {
  16. const char *file_hdr_filename = (const char *)&file_hdr[1];
  17. mem_data = (uint8_t *)file_hdr_filename;
  18. mem_data += file_hdr->filename_len;
  19. mem_data += file_hdr->extra_len;
  20. if (!strncmp(file_hdr_filename, filename, file_hdr->filename_len)) {
  21. /* We found a match */
  22. return file_hdr;
  23. }
  24. mem_data += file_hdr->uncompressed_size;
  25. file_hdr = (const MEMZIP_FILE_HDR *)mem_data;
  26. }
  27. return NULL;
  28. }
  29. bool memzip_is_dir(const char *filename) {
  30. const MEMZIP_FILE_HDR *file_hdr = (const MEMZIP_FILE_HDR *)memzip_data;
  31. uint8_t *mem_data;
  32. if (strcmp(filename, "/") == 0) {
  33. // The root directory is a directory.
  34. return true;
  35. }
  36. // Zip filenames don't have a leading /, so we strip it off
  37. if (*filename == '/') {
  38. filename++;
  39. }
  40. size_t filename_len = strlen(filename);
  41. while (file_hdr->signature == MEMZIP_FILE_HEADER_SIGNATURE) {
  42. const char *file_hdr_filename = (const char *)&file_hdr[1];
  43. if (filename_len < file_hdr->filename_len &&
  44. strncmp(file_hdr_filename, filename, filename_len) == 0 &&
  45. file_hdr_filename[filename_len] == '/') {
  46. return true;
  47. }
  48. mem_data = (uint8_t *)file_hdr_filename;
  49. mem_data += file_hdr->filename_len;
  50. mem_data += file_hdr->extra_len;
  51. mem_data += file_hdr->uncompressed_size;
  52. file_hdr = (const MEMZIP_FILE_HDR *)mem_data;
  53. }
  54. return NULL;
  55. }
  56. MEMZIP_RESULT memzip_locate(const char *filename, void **data, size_t *len)
  57. {
  58. const MEMZIP_FILE_HDR *file_hdr = memzip_find_file_header(filename);
  59. if (file_hdr == NULL) {
  60. return MZ_NO_FILE;
  61. }
  62. if (file_hdr->compression_method != 0) {
  63. return MZ_FILE_COMPRESSED;
  64. }
  65. uint8_t *mem_data;
  66. mem_data = (uint8_t *)&file_hdr[1];
  67. mem_data += file_hdr->filename_len;
  68. mem_data += file_hdr->extra_len;
  69. *data = mem_data;
  70. *len = file_hdr->uncompressed_size;
  71. return MZ_OK;
  72. }
  73. MEMZIP_RESULT memzip_stat(const char *path, MEMZIP_FILE_INFO *info) {
  74. const MEMZIP_FILE_HDR *file_hdr = memzip_find_file_header(path);
  75. if (file_hdr == NULL) {
  76. if (memzip_is_dir(path)) {
  77. info->file_size = 0;
  78. info->last_mod_date = 0;
  79. info->last_mod_time = 0;
  80. info->is_dir = 1;
  81. return MZ_OK;
  82. }
  83. return MZ_NO_FILE;
  84. }
  85. info->file_size = file_hdr->uncompressed_size;
  86. info->last_mod_date = file_hdr->last_mod_date;
  87. info->last_mod_time = file_hdr->last_mod_time;
  88. info->is_dir = 0;
  89. return MZ_OK;
  90. }