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