From 35abd695cdae58fbcef7fafd4c15a6552dc24532 Mon Sep 17 00:00:00 2001 From: Sergey Lyubka Date: Sun, 25 Jul 2021 10:22:56 +0100 Subject: [PATCH] Add packed FS --- examples/complete/Makefile | 19 ++++++++-- examples/complete/main.c | 9 ++--- examples/complete/pack.c | 71 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 7 deletions(-) create mode 100644 examples/complete/pack.c diff --git a/examples/complete/Makefile b/examples/complete/Makefile index 2a081f02..23b87e0c 100644 --- a/examples/complete/Makefile +++ b/examples/complete/Makefile @@ -1,10 +1,23 @@ PROG ?= example +SOURCES ?= ../../mongoose.c main.c mjson.c fs.c +CFLAGS ?= -I../.. $(EXTRA) +FILES_TO_EMBED ?= $(wildcard web_root/*.js) $(wildcard web_root/*.css) $(wildcard web_root/*.html) $(wildcard web_root/images/*.png) $(wildcard images/*.jpg) all: $(PROG) - $(DEBUGGER) ./$(PROG) + $(RUN) ./$(PROG) $(PROG): - $(CC) ../../mongoose.c -I../.. $(CFLAGS) $(EXTRA) -o $(PROG) main.c mjson.c + $(CC) pack.c -o pack + ./pack $(FILES_TO_EMBED) > fs.c + $(CC) -W -Wall -Wextra -O3 -g3 $(CFLAGS) -o $(PROG) $(SOURCES) + +ROOT ?= $(realpath $(CURDIR)/../..) +DOCKER ?= docker run -it --rm -e Tmp=. -e WINEDEBUG=-all -v $(ROOT):$(ROOT) -w $(CURDIR) mdashnet/vc98 wine +windows: + $(DOCKER) cl.exe /nologo $(CFLAGS) pack.c /Fepack.exe + $(DOCKER) cmd /c 'pack.exe $(FILES_TO_EMBED) > fs.c' + $(DOCKER) cl.exe /nologo /O2 $(CFLAGS) $(SOURCES) ws2_32.lib /Fe$(PROG).exe + $(DOCKER) $(PROG).exe clean: - rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt + rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb log.txt fs.c pack diff --git a/examples/complete/main.c b/examples/complete/main.c index 3d948380..67d2f780 100644 --- a/examples/complete/main.c +++ b/examples/complete/main.c @@ -36,13 +36,13 @@ static bool update_config(struct mg_http_message *hm, struct config *cfg) { char buf[256]; double dv; if (mjson_get_number(hm->body.ptr, hm->body.len, "$.value1", &dv)) { - s_config.value1 = dv; + cfg->value1 = dv; changed = true; } if (mjson_get_string(hm->body.ptr, hm->body.len, "$.value2", buf, sizeof(buf)) > 0) { - free(s_config.value2); - s_config.value2 = strdup(buf); + free(cfg->value2); + cfg->value2 = strdup(buf); changed = true; } return changed; @@ -129,7 +129,8 @@ static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { u->token); mg_http_printf_chunk(c, ""); } else { - struct mg_http_serve_opts opts = {.root_dir = "web_root"}; + struct mg_http_serve_opts opts = {0}; + opts.root_dir = "web_root"; mg_http_serve_dir(c, ev_data, &opts); } } diff --git a/examples/complete/pack.c b/examples/complete/pack.c new file mode 100644 index 00000000..7c5d1adc --- /dev/null +++ b/examples/complete/pack.c @@ -0,0 +1,71 @@ +// Copyright (c) Cesanta Software Limited +// All rights reserved. + +// This program is used to pack arbitrary data into a C binary. It takes +// a list of files as an input, and produces a .c data file that contains +// contents of all these files as a collection of byte arrays. +// +// Usage: +// 1. Compile this file: +// cc -o pack pack.c +// +// 2. Convert list of files into single .c: +// ./pack file1.data file2.data > fs.c +// +// 3. In your application code, you can access files using this function: +// const char *unpack(const char *file_name, size_t *size); +// +// 4. Build your app with fs.c: +// cc -o my_app my_app.c fs.c + +#include +#include + +static const char *code = + "const char *unpack(const char *name, size_t *size) {\n" + " const struct packed_file *p;\n" + " for (p = packed_files; p->name != NULL; p++) {\n" + " if (strcmp(p->name, name) != 0) continue;\n" + " if (size != NULL) *size = p->size - 1;\n" + " return (const char *) p->data;\n" + " }\n" + " return NULL;\n" + "}\n"; + +int main(int argc, char *argv[]) { + int i, j, ch; + + printf("%s", "#include \n"); + printf("%s", "#include \n"); + printf("%s", "\n"); + + for (i = 1; i < argc; i++) { + FILE *fp = fopen(argv[i], "rb"); + if (fp == NULL) exit(EXIT_FAILURE); + + printf("static const unsigned char v%d[] = {", i); + for (j = 0; (ch = fgetc(fp)) != EOF; j++) { + if ((j % 12) == 0) printf("%s", "\n "); + printf(" %3u,", ch); + } + // Append zero byte at the end, to make text files appear in memory + // as nul-terminated strings. + printf("%s", " 0x00\n};\n"); + fclose(fp); + } + + printf("%s", "\nconst struct packed_file {\n"); + printf("%s", " const char *name;\n"); + printf("%s", " const unsigned char *data;\n"); + printf("%s", " size_t size;\n"); + printf("%s", "} packed_files[] = {\n"); + + for (i = 1; i < argc; i++) { + printf(" {\"%s\", v%d, sizeof(v%d) },\n", argv[i], i, i); + } + printf("%s", " {NULL, NULL, 0}\n"); + printf("%s", "};\n\n"); + printf("%s", code); + + return EXIT_SUCCESS; +}