Skip to content

Commit 23bf379

Browse files
authored
Merge pull request #60 from InfiniTimeOrg/littlefs-do_install_ressource
littlefs-do: unzip in memory and copy listed resources to SPI raw file
2 parents 6e423c9 + 2306807 commit 23bf379

File tree

18 files changed

+35265
-0
lines changed

18 files changed

+35265
-0
lines changed

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,3 +336,8 @@ target_link_libraries(littlefs-do PUBLIC littlefs)
336336

337337
target_link_libraries(littlefs-do PRIVATE SDL2::SDL2)
338338
target_link_libraries(littlefs-do PRIVATE infinitime_fonts)
339+
340+
add_subdirectory(external/miniz)
341+
add_subdirectory(external/nlohmann_json)
342+
target_link_libraries(littlefs-do PRIVATE miniz)
343+
target_link_libraries(littlefs-do PRIVATE nlohmann_json::nlohmann_json)

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,20 @@ Commands:
133133
rm remove directory or file
134134
cp copy files into or out of flash file
135135
settings list settings from 'settings.h'
136+
res resource.zip handling
137+
```
138+
139+
### Resource loading
140+
141+
To load resource zip files into the SPI raw file for the simulator to use the `res load` command can be used.
142+
143+
```sh
144+
$ ./littlefs-do res --help
145+
Usage: ./littlefs-do res <action> [options]
146+
actions:
147+
load res.zip load zip file into SPI memory
148+
Options:
149+
-h, --help show this help message for the selected command and exit
136150
```
137151

138152
## Licenses

external/miniz/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
add_library(miniz STATIC
3+
miniz.h
4+
miniz.c
5+
)
6+
target_include_directories(miniz PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")

external/miniz/ChangeLog.md

Lines changed: 196 additions & 0 deletions
Large diffs are not rendered by default.

external/miniz/LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Copyright 2013-2014 RAD Game Tools and Valve Software
2+
Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
3+
4+
All Rights Reserved.
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in
14+
all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
THE SOFTWARE.

external/miniz/download-url.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
https://github.com/richgel999/miniz/releases/tag/2.2.0

external/miniz/examples/example1.c

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// example1.c - Demonstrates miniz.c's compress() and uncompress() functions (same as zlib's).
2+
// Public domain, May 15 2011, Rich Geldreich, [email protected]. See "unlicense" statement at the end of tinfl.c.
3+
#include <stdio.h>
4+
#include "miniz.h"
5+
typedef unsigned char uint8;
6+
typedef unsigned short uint16;
7+
typedef unsigned int uint;
8+
9+
// The string to compress.
10+
static const char *s_pStr = "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
11+
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
12+
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
13+
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
14+
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
15+
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
16+
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson.";
17+
18+
int main(int argc, char *argv[])
19+
{
20+
uint step = 0;
21+
int cmp_status;
22+
uLong src_len = (uLong)strlen(s_pStr);
23+
uLong cmp_len = compressBound(src_len);
24+
uLong uncomp_len = src_len;
25+
uint8 *pCmp, *pUncomp;
26+
uint total_succeeded = 0;
27+
(void)argc, (void)argv;
28+
29+
printf("miniz.c version: %s\n", MZ_VERSION);
30+
31+
do
32+
{
33+
// Allocate buffers to hold compressed and uncompressed data.
34+
pCmp = (mz_uint8 *)malloc((size_t)cmp_len);
35+
pUncomp = (mz_uint8 *)malloc((size_t)src_len);
36+
if ((!pCmp) || (!pUncomp))
37+
{
38+
printf("Out of memory!\n");
39+
return EXIT_FAILURE;
40+
}
41+
42+
// Compress the string.
43+
cmp_status = compress(pCmp, &cmp_len, (const unsigned char *)s_pStr, src_len);
44+
if (cmp_status != Z_OK)
45+
{
46+
printf("compress() failed!\n");
47+
free(pCmp);
48+
free(pUncomp);
49+
return EXIT_FAILURE;
50+
}
51+
52+
printf("Compressed from %u to %u bytes\n", (mz_uint32)src_len, (mz_uint32)cmp_len);
53+
54+
if (step)
55+
{
56+
// Purposely corrupt the compressed data if fuzzy testing (this is a very crude fuzzy test).
57+
uint n = 1 + (rand() % 3);
58+
while (n--)
59+
{
60+
uint i = rand() % cmp_len;
61+
pCmp[i] ^= (rand() & 0xFF);
62+
}
63+
}
64+
65+
// Decompress.
66+
cmp_status = uncompress(pUncomp, &uncomp_len, pCmp, cmp_len);
67+
total_succeeded += (cmp_status == Z_OK);
68+
69+
if (step)
70+
{
71+
printf("Simple fuzzy test: step %u total_succeeded: %u\n", step, total_succeeded);
72+
}
73+
else
74+
{
75+
if (cmp_status != Z_OK)
76+
{
77+
printf("uncompress failed!\n");
78+
free(pCmp);
79+
free(pUncomp);
80+
return EXIT_FAILURE;
81+
}
82+
83+
printf("Decompressed from %u to %u bytes\n", (mz_uint32)cmp_len, (mz_uint32)uncomp_len);
84+
85+
// Ensure uncompress() returned the expected data.
86+
if ((uncomp_len != src_len) || (memcmp(pUncomp, s_pStr, (size_t)src_len)))
87+
{
88+
printf("Decompression failed!\n");
89+
free(pCmp);
90+
free(pUncomp);
91+
return EXIT_FAILURE;
92+
}
93+
}
94+
95+
free(pCmp);
96+
free(pUncomp);
97+
98+
step++;
99+
100+
// Keep on fuzzy testing if there's a non-empty command line.
101+
} while (argc >= 2);
102+
103+
printf("Success.\n");
104+
return EXIT_SUCCESS;
105+
}

external/miniz/examples/example2.c

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
// example2.c - Simple demonstration of miniz.c's ZIP archive API's.
2+
// Note this test deletes the test archive file "__mz_example2_test__.zip" in the current directory, then creates a new one with test data.
3+
// Public domain, May 15 2011, Rich Geldreich, [email protected]. See "unlicense" statement at the end of tinfl.c.
4+
5+
#if defined(__GNUC__)
6+
// Ensure we get the 64-bit variants of the CRT's file I/O calls
7+
#ifndef _FILE_OFFSET_BITS
8+
#define _FILE_OFFSET_BITS 64
9+
#endif
10+
#ifndef _LARGEFILE64_SOURCE
11+
#define _LARGEFILE64_SOURCE 1
12+
#endif
13+
#endif
14+
15+
#include <stdio.h>
16+
#include "miniz.h"
17+
18+
typedef unsigned char uint8;
19+
typedef unsigned short uint16;
20+
typedef unsigned int uint;
21+
22+
// The string to compress.
23+
static const char *s_pTest_str =
24+
"MISSION CONTROL I wouldn't worry too much about the computer. First of all, there is still a chance that he is right, despite your tests, and" \
25+
"if it should happen again, we suggest eliminating this possibility by allowing the unit to remain in place and seeing whether or not it" \
26+
"actually fails. If the computer should turn out to be wrong, the situation is still not alarming. The type of obsessional error he may be" \
27+
"guilty of is not unknown among the latest generation of HAL 9000 computers. It has almost always revolved around a single detail, such as" \
28+
"the one you have described, and it has never interfered with the integrity or reliability of the computer's performance in other areas." \
29+
"No one is certain of the cause of this kind of malfunctioning. It may be over-programming, but it could also be any number of reasons. In any" \
30+
"event, it is somewhat analogous to human neurotic behavior. Does this answer your query? Zero-five-three-Zero, MC, transmission concluded.";
31+
32+
static const char *s_pComment = "This is a comment";
33+
34+
int main(int argc, char *argv[])
35+
{
36+
int i, sort_iter;
37+
mz_bool status;
38+
size_t uncomp_size;
39+
mz_zip_archive zip_archive;
40+
void *p;
41+
const int N = 50;
42+
char data[2048];
43+
char archive_filename[64];
44+
static const char *s_Test_archive_filename = "__mz_example2_test__.zip";
45+
46+
assert((strlen(s_pTest_str) + 64) < sizeof(data));
47+
48+
printf("miniz.c version: %s\n", MZ_VERSION);
49+
50+
(void)argc, (void)argv;
51+
52+
// Delete the test archive, so it doesn't keep growing as we run this test
53+
remove(s_Test_archive_filename);
54+
55+
// Append a bunch of text files to the test archive
56+
for (i = (N - 1); i >= 0; --i)
57+
{
58+
sprintf(archive_filename, "%u.txt", i);
59+
sprintf(data, "%u %s %u", (N - 1) - i, s_pTest_str, i);
60+
61+
// Add a new file to the archive. Note this is an IN-PLACE operation, so if it fails your archive is probably hosed (its central directory may not be complete) but it should be recoverable using zip -F or -FF. So use caution with this guy.
62+
// A more robust way to add a file to an archive would be to read it into memory, perform the operation, then write a new archive out to a temp file and then delete/rename the files.
63+
// Or, write a new archive to disk to a temp file, then delete/rename the files. For this test this API is fine.
64+
status = mz_zip_add_mem_to_archive_file_in_place(s_Test_archive_filename, archive_filename, data, strlen(data) + 1, s_pComment, (uint16)strlen(s_pComment), MZ_BEST_COMPRESSION);
65+
if (!status)
66+
{
67+
printf("mz_zip_add_mem_to_archive_file_in_place failed!\n");
68+
return EXIT_FAILURE;
69+
}
70+
}
71+
72+
// Add a directory entry for testing
73+
status = mz_zip_add_mem_to_archive_file_in_place(s_Test_archive_filename, "directory/", NULL, 0, "no comment", (uint16)strlen("no comment"), MZ_BEST_COMPRESSION);
74+
if (!status)
75+
{
76+
printf("mz_zip_add_mem_to_archive_file_in_place failed!\n");
77+
return EXIT_FAILURE;
78+
}
79+
80+
// Now try to open the archive.
81+
memset(&zip_archive, 0, sizeof(zip_archive));
82+
83+
status = mz_zip_reader_init_file(&zip_archive, s_Test_archive_filename, 0);
84+
if (!status)
85+
{
86+
printf("mz_zip_reader_init_file() failed!\n");
87+
return EXIT_FAILURE;
88+
}
89+
90+
// Get and print information about each file in the archive.
91+
for (i = 0; i < (int)mz_zip_reader_get_num_files(&zip_archive); i++)
92+
{
93+
mz_zip_archive_file_stat file_stat;
94+
if (!mz_zip_reader_file_stat(&zip_archive, i, &file_stat))
95+
{
96+
printf("mz_zip_reader_file_stat() failed!\n");
97+
mz_zip_reader_end(&zip_archive);
98+
return EXIT_FAILURE;
99+
}
100+
101+
printf("Filename: \"%s\", Comment: \"%s\", Uncompressed size: %u, Compressed size: %u, Is Dir: %u\n", file_stat.m_filename, file_stat.m_comment, (uint)file_stat.m_uncomp_size, (uint)file_stat.m_comp_size, mz_zip_reader_is_file_a_directory(&zip_archive, i));
102+
103+
if (!strcmp(file_stat.m_filename, "directory/"))
104+
{
105+
if (!mz_zip_reader_is_file_a_directory(&zip_archive, i))
106+
{
107+
printf("mz_zip_reader_is_file_a_directory() didn't return the expected results!\n");
108+
mz_zip_reader_end(&zip_archive);
109+
return EXIT_FAILURE;
110+
}
111+
}
112+
}
113+
114+
// Close the archive, freeing any resources it was using
115+
mz_zip_reader_end(&zip_archive);
116+
117+
// Now verify the compressed data
118+
for (sort_iter = 0; sort_iter < 2; sort_iter++)
119+
{
120+
memset(&zip_archive, 0, sizeof(zip_archive));
121+
status = mz_zip_reader_init_file(&zip_archive, s_Test_archive_filename, sort_iter ? MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY : 0);
122+
if (!status)
123+
{
124+
printf("mz_zip_reader_init_file() failed!\n");
125+
return EXIT_FAILURE;
126+
}
127+
128+
for (i = 0; i < N; i++)
129+
{
130+
sprintf(archive_filename, "%u.txt", i);
131+
sprintf(data, "%u %s %u", (N - 1) - i, s_pTest_str, i);
132+
133+
// Try to extract all the files to the heap.
134+
p = mz_zip_reader_extract_file_to_heap(&zip_archive, archive_filename, &uncomp_size, 0);
135+
if (!p)
136+
{
137+
printf("mz_zip_reader_extract_file_to_heap() failed!\n");
138+
mz_zip_reader_end(&zip_archive);
139+
return EXIT_FAILURE;
140+
}
141+
142+
// Make sure the extraction really succeeded.
143+
if ((uncomp_size != (strlen(data) + 1)) || (memcmp(p, data, strlen(data))))
144+
{
145+
printf("mz_zip_reader_extract_file_to_heap() failed to extract the proper data\n");
146+
mz_free(p);
147+
mz_zip_reader_end(&zip_archive);
148+
return EXIT_FAILURE;
149+
}
150+
151+
printf("Successfully extracted file \"%s\", size %u\n", archive_filename, (uint)uncomp_size);
152+
printf("File data: \"%s\"\n", (const char *)p);
153+
154+
// We're done.
155+
mz_free(p);
156+
}
157+
158+
// Close the archive, freeing any resources it was using
159+
mz_zip_reader_end(&zip_archive);
160+
}
161+
162+
printf("Success.\n");
163+
return EXIT_SUCCESS;
164+
}

0 commit comments

Comments
 (0)